తేదీ పరిధిలో రికార్డులను క్వెరీ చేయడం — “గత 30 రోజుల్లో ఉన్నవన్నీ చూపించు,” “జనవరి 1 నుంచి మార్చి 31 మధ్య ఉన్న ఆర్డర్లను కనుగొను” — ఏ డేటాబేస్ ఆధారిత అప్లికేషన్లోనూ అత్యంత సాధారణ ఆపరేషన్లలో ఒకటి. టైమ్స్టాంప్లను ఎలా నిల్వ చేస్తారు, ఎలా క్వెరీ చేస్తారు అనేదే ఆ క్వెరీలు ఎంత సులభంగా, ఎంత నమ్మకంగా పనిచేస్తాయో బాగా ప్రభావితం చేస్తుంది.
Unix టైమ్స్టాంప్లు (Unix epoch నుంచి గడిచిన సెకన్లను సూచించే పూర్ణసంఖ్యలు) ఇందుకు చాలాసార్లు ఉత్తమ ఎంపిక. కానీ వాటిని సరిగా ఎలా ఉపయోగించాలో తెలిసి ఉండాలి. ఇక్కడ ప్రాయోగిక మార్గదర్శకం ఉంది.
Unix టైమ్స్టాంప్లు రేంజ్ క్వెరీలను ఎందుకు సులభం చేస్తాయి
టైమ్స్టాంప్లను పూర్ణసంఖ్యలుగా నిల్వ చేస్తే, తేదీ పరిధి క్వెరీ ఒక సాదా సంఖ్యాత్మక పోలికగా మారుతుంది:
SELECT * FROM events
WHERE created_at >= 1704067200
AND created_at < 1706745600;
అంతే. స్ట్రింగ్ పార్సింగ్ లేదు, టైమ్జోన్ కన్వర్షన్ లేదు, BETWEEN సేమాంటిక్స్ గురించి ఆలోచించాల్సిన అవసరం లేదు. డేటాబేస్ రెండు పూర్ణసంఖ్యలను పోల్చుతుంది.
ఫార్మాట్ చేసిన datetime స్ట్రింగ్ పద్ధతితో పోల్చండి:
SELECT * FROM events
WHERE created_at >= '2024-01-01 00:00:00'
AND created_at < '2024-02-01 00:00:00';
ఇది కూడా పోలి కనిపిస్తుంది, కానీ కొన్ని ప్రశ్నలను తెస్తుంది: '2024-01-01 00:00:00' ఏ టైమ్జోన్లో ఉంది? మీ అప్లికేషన్ సర్వర్ అదే విధంగా అర్థం చేసుకుంటుందా డేటాబేస్ సర్వర్? వేర్వేరు టైమ్జోన్లలో ఉన్న యూజర్లు ఇదే క్వెరీ నడిపితే ఏమవుతుంది?
Unix టైమ్స్టాంప్లు ఇవన్నీ తప్పిస్తాయి. అవి ఎప్పుడూ UTC, ఎప్పుడూ సందిగ్ధత లేని విధంగా, ఎప్పుడూ ఒక సంఖ్య. లోకల్ టైమ్కి మార్పు క్వెరీలో కాదు — ప్రదర్శించే (display) లేయర్లో జరుగుతుంది.
సాధారణ తేదీ పరిధుల కోసం టైమ్స్టాంప్లను ఎలా లెక్కించాలి
రేంజ్ క్వెరీ రాయాలంటే, ఆ పరిధి ప్రారంభం మరియు ముగింపుకు Unix టైమ్స్టాంప్లు కావాలి. Unix టైమ్స్టాంప్ కన్వర్టర్ దీన్ని సులభం చేస్తుంది — తేదీని ఇవ్వండి, టైమ్స్టాంప్ను పొందండి.
సాధారణ క్వెరీ నమూనాల కోసం లెక్కలు ఇవి:
గత N రోజులు: ` start = current_timestamp - (N × 86400) end = current_timestamp `
గత 7 రోజులు: start = now - 604800 (7 × 86,400 సెకన్లు) గత 30 రోజులు: start = now - 2592000 (30 × 86,400) గత 90 రోజులు: start = now - 7776000
ఒక నిర్దిష్ట క్యాలెండర్ నెల (ఉదా., మార్చి 2024): ` start = Unix timestamp of 2024-03-01 00:00:00 UTC = 1709251200 end = Unix timestamp of 2024-04-01 00:00:00 UTC = 1711929600 `
క్వెరీ: WHERE created_at >= 1709251200 AND created_at < 1711929600
గమనిక: తదుపరి రోజు అర్ధరాత్రిని ఎండ్ బౌండరీగా ఉపయోగిస్తున్నప్పుడు <= కన్నా < (less than) ఉపయోగించండి. అప్పుడు మార్చి 31 చివరి సెకన్ ఏమిటి అనే తలనొప్పి లేకుండా, ఏప్రిల్ 1 లోని రికార్డులు శుభ్రంగా బయట పడతాయి.
Year to date: ` start = Unix timestamp of January 1 of current year, 00:00:00 UTC end = current timestamp `
రెండు తేదీల మధ్య స్థిర తేదీ పరిధి: కన్వర్టర్తో రెండు తేదీలను UTC అర్ధరాత్రి టైమ్స్టాంప్లుగా మార్చి, వాటినే బౌండరీలుగా నేరుగా ఉపయోగించండి.
టైమ్జోన్లను సరిగా ఎలా హ్యాండిల్ చేయాలి
Unix టైమ్స్టాంప్ రేంజ్ క్వెరీలలో అత్యంత సాధారణ పొరపాటు బౌండరీ టైమ్స్టాంప్లను సృష్టించే సమయంలో టైమ్జోన్ గందరగోళం.
Unix టైమ్స్టాంప్లు ఎప్పుడూ UTC. మీ అప్లికేషన్కు “న్యూయార్క్ టైమ్ (UTC-4) ప్రకారం ఏప్రిల్ 8న చేసిన ఆర్డర్లు” క్వెరీ చేయాలి అంటే, న్యూయార్క్లో ఏప్రిల్ 8 ఈ పరిధిని కవర్ చేస్తుంది:
2024-04-08 00:00:00 EDT=2024-04-08 04:00:00 UTC= Unix టైమ్స్టాంప్17125452002024-04-09 00:00:00 EDT=2024-04-09 04:00:00 UTC= Unix టైమ్స్టాంప్1712631600
మీరు అమాయకంగా UTC అర్ధరాత్రిని వాడితే:
2024-04-08 00:00:00 UTC= Unix టైమ్స్టాంప్1712534400
అప్పుడు న్యూయార్క్ టైమ్ ప్రకారం ఏప్రిల్ 7 చివరి 4 గంటల రికార్డులు తప్పుగా కలుస్తాయి, అలాగే ఏప్రిల్ 8 చివరి 4 గంటల రికార్డులు మిస్సవుతాయి.
సరైన విధానం: బౌండరీ టైమ్స్టాంప్లను సృష్టించే ముందు మీ తేదీ పరిధిని ఎప్పుడూ UTCకి మార్చండి. కోడ్లో:
import datetime, pytz
tz = pytz.timezone('America/New_York')
start_local = tz.localize(datetime.datetime(2024, 4, 8, 0, 0, 0))
start_utc_ts = int(start_local.utctimetuple().tm_sec) # or .timestamp()
లేదా టైమ్జోన్-అవేర్ టైమ్స్టాంప్లను సరిగా నిర్వహించే తేదీ లైబ్రరీని ఉపయోగించండి. ముఖ్య సూత్రం: యూజర్ లోకల్ టైమ్లో బౌండరీలను సృష్టించండి, UTCకి మార్చండి, ఆ తర్వాత వచ్చిన పూర్ణసంఖ్యను క్వెరీలో ఉపయోగించండి.
పనితీరు కోసం ఇండెక్సింగ్
టైమ్స్టాంప్ రేంజ్ క్వెరీలు వేగంగా ఉండాలంటే, టైమ్స్టాంప్ కాలమ్కు ఇండెక్స్ ఉండాలి. లక్షల/కోట్ల రోల్స్ ఉన్న టేబుల్లో, ఇండెక్స్ లేకుండా తేదీ పరిధి కోసం integer స్కాన్ నెమ్మదిగా ఉంటుంది — క్వెరీ ఎంత సాదాగా కనిపించినా.
PostgreSQL: `sql CREATE INDEX idx_events_created_at ON events (created_at); `
MySQL: `sql ALTER TABLE events ADD INDEX idx_created_at (created_at); `
టైమ్స్టాంప్ రేంజ్లను ఇతర ఫిల్టర్లతో తరచుగా కలిపి క్వెరీ చేస్తే (ఉదా., WHERE user_id = 123 AND created_at >= X), సాధారణంగా అత్యంత సెలెక్టివ్ కాలమ్ ముందుగా ఉండే కాంపోజిట్ ఇండెక్స్ వేగంగా ఉంటుంది:
CREATE INDEX idx_events_user_created ON events (user_id, created_at);
కాంపోజిట్ ఇండెక్స్లు డేటాబేస్కు ముందుగా యూజర్ ద్వారా పరిధిని తగ్గించి, ఆ యూజర్కు సంబంధించిన టైమ్-ఆర్డర్డ్ రికార్డులపై మాత్రమే రేంజ్ స్కాన్ చేయడానికి సహాయపడతాయి.
సాధారణ భాషలలో టైమ్స్టాంప్ బౌండరీలను ఎలా రూపొందించాలి
JavaScript: `javascript const now = Math.floor(Date.now() / 1000); const last30Days = now - (30 * 86400); // Query: WHERE created_at >= last30Days AND created_at <= now `
Python: `python import time now = int(time.time()) last_30_days = now - (30 * 86400) `
ఒక నిర్దిష్ట UTC తేదీ కోసం: `python import datetime dt = datetime.datetime(2024, 1, 1, tzinfo=datetime.timezone.utc) ts = int(dt.timestamp()) # 1704067200 `
PHP: `php $now = time(); $start = mktime(0, 0, 0, 1, 1, 2024); // Jan 1 2024 midnight local time // Use strtotime for UTC: strtotime('2024-01-01 00:00:00 UTC') `
SQL (PostgreSQL) — బౌండరీని ఇన్లైన్గా రూపొందించడం: `sql SELECT * FROM events WHERE created_at >= EXTRACT(EPOCH FROM NOW() - INTERVAL '30 days')::int AND created_at <= EXTRACT(EPOCH FROM NOW())::int; `
తప్పించుకోవాల్సిన సాధారణ పొరపాట్లు
UTC అర్ధరాత్రి బదులు లోకల్ అర్ధరాత్రిని వాడటం. మీ అప్లికేషన్ సర్వర్ UTCకి భిన్నమైన టైమ్జోన్లో ఉంటే, JavaScriptలో new Date().setHours(0,0,0,0) సర్వర్ లోకల్ టైమ్జోన్లో అర్ధరాత్రిని ఇస్తుంది — UTC కాదు. టైమ్జోన్ విషయంలో ఎప్పుడూ స్పష్టంగా ఉండండి.
ఎండ్ బౌండరీలలో off-by-one. created_at <= 1711929599 (మార్చి 31 చివరి సెకన్) మరియు created_at < 1711929600 (ఏప్రిల్ 1 అర్ధరాత్రి) సమానమే, కానీ రెండో రూపం శుభ్రంగా ఉంటుంది; మీరు ఎప్పుడైనా మిల్లీ సెకండ్లకు మారితే కూడా ఉప-సెకండ్ ఎడ్జ్ కేసులను తప్పిస్తుంది.
DST మార్పులను మర్చిపోవడం. డేలైట్ సేవింగ్ టైమ్ ఉన్న టైమ్జోన్లలో, ఏడాదిలో ఒక రోజు 23 గంటలు, మరో రోజు 25 గంటలు ఉంటుంది. ఇది “గత 24 గంటలు” లెక్కలపై ప్రభావం చూపుతుంది: now - 86400 లోకల్ టైమ్లో “నిన్న ఇదే సమయం” కాదని కొన్ని సందర్భాల్లో వస్తుంది. ఖచ్చితమైన లోకల్-డే క్వెరీల కోసం, స్థిర సెకండ్లను తీసివేయడం బదులు లోకల్ క్యాలెండర్ తేదీ నుంచి బౌండరీలను స్పష్టంగా సృష్టించండి.
టైమ్స్టాంప్ కాలమ్కు ఇండెక్స్ లేకపోవడం. సూత్రంగా స్పష్టమే, కానీ ప్రారంభ దశలో టేబుళ్లు చిన్నగా ఉన్నప్పుడు క్వెరీలు నెమ్మదిగా ఉన్నట్లు కనిపించక మిస్ అవుతుంది.
డిప్లాయ్ చేసే ముందు మీ బౌండరీ టైమ్స్టాంప్లు సరైనవో కాదో చూసేందుకు Unix టైమ్స్టాంప్ కన్వర్టర్ ఉపయోగించండి — పూర్ణసంఖ్యను పేస్ట్ చేసి, అది మీరు ఆశించిన తేదీ/సమయంగా మారుతోందో ధృవీకరించండి.