[{"data":1,"prerenderedAt":1461},["ShallowReactive",2],{"blog-\u002Fblog\u002Fsql-date-time-functions":3},{"id":4,"title":5,"body":6,"description":1447,"difficulty":1448,"extension":1449,"framework":1450,"frameworkSlug":53,"meta":1451,"navigation":99,"order":68,"path":1452,"qaPath":1453,"seo":1454,"stem":1455,"subtopic":1456,"topic":1457,"topicSlug":1458,"updated":1459,"__hash__":1460},"blog\u002Fblog\u002Fsql-date-time-functions.md","SQL Date & Time Functions — NOW, DATE_TRUNC, EXTRACT, and Intervals",{"type":7,"value":8,"toc":1436},"minimark",[9,14,44,48,195,210,214,220,430,447,451,457,673,677,872,882,921,927,970,974,1106,1110,1261,1265,1398,1402,1432],[10,11,13],"h2",{"id":12},"dates-are-not-strings","Dates are not strings",[15,16,17,18,27,28,31,32,35,36,39,40,43],"p",{},"The single most important rule in SQL date handling: ",[19,20,21,22,26],"strong",{},"store timestamps as\n",[23,24,25],"code",{},"TIMESTAMPTZ",", not as strings",". String dates (",[23,29,30],{},"'2026-06-20'"," in a ",[23,33,34],{},"VARCHAR","\ncolumn) cannot be compared with ",[23,37,38],{},"\u003C"," \u002F ",[23,41,42],{},">",", cannot be indexed efficiently, and\nbreak sorting. Use proper date\u002Ftime types so the database can index, compare,\nand truncate them correctly.",[10,45,47],{"id":46},"getting-the-current-date-and-time","Getting the current date and time",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-sql shiki shiki-themes github-light github-dark","-- Current timestamp with time zone (use this for created_at \u002F updated_at)\nSELECT NOW();                  -- '2026-06-20 14:35:22.451+01'\nSELECT CURRENT_TIMESTAMP;      -- same, SQL standard alias\n\n-- Current date only (no time)\nSELECT CURRENT_DATE;           -- '2026-06-20'\n\n-- Current time only\nSELECT CURRENT_TIME;           -- '14:35:22.451+01'\n\n-- MySQL equivalents\nSELECT NOW(), CURDATE(), CURTIME(), UTC_TIMESTAMP();\n\n-- SQL Server equivalents\nSELECT GETDATE(), GETUTCDATE(), SYSDATETIMEOFFSET();\n","sql","",[23,56,57,66,83,94,101,107,118,123,129,140,145,151,161,166,172],{"__ignoreMap":54},[58,59,62],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"sJ8bj","-- Current timestamp with time zone (use this for created_at \u002F updated_at)\n",[58,67,69,73,76,80],{"class":60,"line":68},2,[58,70,72],{"class":71},"szBVR","SELECT",[58,74,75],{"class":71}," NOW",[58,77,79],{"class":78},"sVt8B","();                  ",[58,81,82],{"class":64},"-- '2026-06-20 14:35:22.451+01'\n",[58,84,86,88,91],{"class":60,"line":85},3,[58,87,72],{"class":71},[58,89,90],{"class":78}," CURRENT_TIMESTAMP;      ",[58,92,93],{"class":64},"-- same, SQL standard alias\n",[58,95,97],{"class":60,"line":96},4,[58,98,100],{"emptyLinePlaceholder":99},true,"\n",[58,102,104],{"class":60,"line":103},5,[58,105,106],{"class":64},"-- Current date only (no time)\n",[58,108,110,112,115],{"class":60,"line":109},6,[58,111,72],{"class":71},[58,113,114],{"class":78}," CURRENT_DATE;           ",[58,116,117],{"class":64},"-- '2026-06-20'\n",[58,119,121],{"class":60,"line":120},7,[58,122,100],{"emptyLinePlaceholder":99},[58,124,126],{"class":60,"line":125},8,[58,127,128],{"class":64},"-- Current time only\n",[58,130,132,134,137],{"class":60,"line":131},9,[58,133,72],{"class":71},[58,135,136],{"class":78}," CURRENT_TIME;           ",[58,138,139],{"class":64},"-- '14:35:22.451+01'\n",[58,141,143],{"class":60,"line":142},10,[58,144,100],{"emptyLinePlaceholder":99},[58,146,148],{"class":60,"line":147},11,[58,149,150],{"class":64},"-- MySQL equivalents\n",[58,152,154,156,158],{"class":60,"line":153},12,[58,155,72],{"class":71},[58,157,75],{"class":71},[58,159,160],{"class":78},"(), CURDATE(), CURTIME(), UTC_TIMESTAMP();\n",[58,162,164],{"class":60,"line":163},13,[58,165,100],{"emptyLinePlaceholder":99},[58,167,169],{"class":60,"line":168},14,[58,170,171],{"class":64},"-- SQL Server equivalents\n",[58,173,175,177,181,184,187,189,192],{"class":60,"line":174},15,[58,176,72],{"class":71},[58,178,180],{"class":179},"sj4cs"," GETDATE",[58,182,183],{"class":78},"(), ",[58,185,186],{"class":179},"GETUTCDATE",[58,188,183],{"class":78},[58,190,191],{"class":179},"SYSDATETIMEOFFSET",[58,193,194],{"class":78},"();\n",[15,196,197,198,201,202,205,206,209],{},"Always use ",[23,199,200],{},"NOW()"," (which returns the transaction start time) rather than\n",[23,203,204],{},"CLOCK_TIMESTAMP()"," (current clock at the moment of the call) for ",[23,207,208],{},"created_at","\ncolumns — all rows in one transaction get the same timestamp.",[10,211,213],{"id":212},"date_trunc-grouping-by-time-period","DATE_TRUNC — grouping by time period",[15,215,216,219],{},[23,217,218],{},"DATE_TRUNC"," rounds a timestamp down to a specified unit. It is the key to\ngrouping rows by hour, day, week, month, or year.",[49,221,223],{"className":51,"code":222,"language":53,"meta":54,"style":54},"-- Daily revenue for the last 30 days\nSELECT\n    DATE_TRUNC('day', created_at) AS order_date,\n    COUNT(*)                       AS orders,\n    SUM(total_amount)              AS revenue\nFROM orders\nWHERE  created_at >= NOW() - INTERVAL '30 days'\n  AND  status = 'completed'\nGROUP  BY DATE_TRUNC('day', created_at)\nORDER  BY order_date;\n\n-- Monthly active users (users who placed at least one order per month)\nSELECT\n    DATE_TRUNC('month', created_at) AS month,\n    COUNT(DISTINCT customer_id)      AS mau\nFROM orders\nGROUP BY DATE_TRUNC('month', created_at)\nORDER BY month;\n",[23,224,225,230,235,253,272,285,293,318,332,345,353,357,362,366,383,400,407,419],{"__ignoreMap":54},[58,226,227],{"class":60,"line":61},[58,228,229],{"class":64},"-- Daily revenue for the last 30 days\n",[58,231,232],{"class":60,"line":68},[58,233,234],{"class":71},"SELECT\n",[58,236,237,240,244,247,250],{"class":60,"line":85},[58,238,239],{"class":78},"    DATE_TRUNC(",[58,241,243],{"class":242},"sZZnC","'day'",[58,245,246],{"class":78},", created_at) ",[58,248,249],{"class":71},"AS",[58,251,252],{"class":78}," order_date,\n",[58,254,255,258,261,264,267,269],{"class":60,"line":96},[58,256,257],{"class":179},"    COUNT",[58,259,260],{"class":78},"(",[58,262,263],{"class":71},"*",[58,265,266],{"class":78},")                       ",[58,268,249],{"class":71},[58,270,271],{"class":78}," orders,\n",[58,273,274,277,280,282],{"class":60,"line":103},[58,275,276],{"class":179},"    SUM",[58,278,279],{"class":78},"(total_amount)              ",[58,281,249],{"class":71},[58,283,284],{"class":78}," revenue\n",[58,286,287,290],{"class":60,"line":109},[58,288,289],{"class":71},"FROM",[58,291,292],{"class":78}," orders\n",[58,294,295,298,301,304,306,309,312,315],{"class":60,"line":120},[58,296,297],{"class":71},"WHERE",[58,299,300],{"class":78},"  created_at ",[58,302,303],{"class":71},">=",[58,305,75],{"class":71},[58,307,308],{"class":78},"() ",[58,310,311],{"class":71},"-",[58,313,314],{"class":78}," INTERVAL ",[58,316,317],{"class":242},"'30 days'\n",[58,319,320,323,326,329],{"class":60,"line":125},[58,321,322],{"class":71},"  AND",[58,324,325],{"class":71},"  status",[58,327,328],{"class":71}," =",[58,330,331],{"class":242}," 'completed'\n",[58,333,334,337,340,342],{"class":60,"line":131},[58,335,336],{"class":71},"GROUP  BY",[58,338,339],{"class":78}," DATE_TRUNC(",[58,341,243],{"class":242},[58,343,344],{"class":78},", created_at)\n",[58,346,347,350],{"class":60,"line":142},[58,348,349],{"class":71},"ORDER  BY",[58,351,352],{"class":78}," order_date;\n",[58,354,355],{"class":60,"line":147},[58,356,100],{"emptyLinePlaceholder":99},[58,358,359],{"class":60,"line":153},[58,360,361],{"class":64},"-- Monthly active users (users who placed at least one order per month)\n",[58,363,364],{"class":60,"line":163},[58,365,234],{"class":71},[58,367,368,370,373,375,377,380],{"class":60,"line":168},[58,369,239],{"class":78},[58,371,372],{"class":242},"'month'",[58,374,246],{"class":78},[58,376,249],{"class":71},[58,378,379],{"class":71}," month",[58,381,382],{"class":78},",\n",[58,384,385,387,389,392,395,397],{"class":60,"line":174},[58,386,257],{"class":179},[58,388,260],{"class":78},[58,390,391],{"class":71},"DISTINCT",[58,393,394],{"class":78}," customer_id)      ",[58,396,249],{"class":71},[58,398,399],{"class":78}," mau\n",[58,401,403,405],{"class":60,"line":402},16,[58,404,289],{"class":71},[58,406,292],{"class":78},[58,408,410,413,415,417],{"class":60,"line":409},17,[58,411,412],{"class":71},"GROUP BY",[58,414,339],{"class":78},[58,416,372],{"class":242},[58,418,344],{"class":78},[58,420,422,425,427],{"class":60,"line":421},18,[58,423,424],{"class":71},"ORDER BY",[58,426,379],{"class":71},[58,428,429],{"class":78},";\n",[15,431,432,434,435,438,439,442,443,446],{},[23,433,218],{}," is Postgres syntax. MySQL equivalent: ",[23,436,437],{},"DATE_FORMAT(col, '%Y-%m-01')","\nfor month truncation. SQL Server: ",[23,440,441],{},"DATETRUNC('month', col)"," (SQL Server 2022+)\nor ",[23,444,445],{},"DATEFROMPARTS(YEAR(col), MONTH(col), 1)",".",[10,448,450],{"id":449},"extract-and-date_part-individual-components","EXTRACT and DATE_PART — individual components",[15,452,453,456],{},[23,454,455],{},"EXTRACT"," pulls out a single component (year, month, day, hour, weekday) from\na timestamp.",[49,458,460],{"className":51,"code":459,"language":53,"meta":54,"style":54},"-- Orders by day of week (1=Sunday in Postgres, 1=Monday in ISO)\nSELECT\n    EXTRACT(DOW FROM created_at) AS day_of_week,\n    COUNT(*)                      AS order_count\nFROM orders\nGROUP BY day_of_week\nORDER BY day_of_week;\n\n-- Orders placed in business hours (9am–5pm)\nSELECT COUNT(*) FROM orders\nWHERE EXTRACT(HOUR FROM created_at AT TIME ZONE 'Europe\u002FLondon') BETWEEN 9 AND 17;\n\n-- Year-over-year comparison\nSELECT\n    EXTRACT(YEAR FROM created_at)  AS yr,\n    EXTRACT(MONTH FROM created_at) AS mo,\n    SUM(total_amount) AS revenue\nFROM orders\nGROUP BY yr, mo\nORDER BY yr, mo;\n",[23,461,462,467,471,486,502,508,515,522,526,531,549,593,597,602,606,624,640,651,657,665],{"__ignoreMap":54},[58,463,464],{"class":60,"line":61},[58,465,466],{"class":64},"-- Orders by day of week (1=Sunday in Postgres, 1=Monday in ISO)\n",[58,468,469],{"class":60,"line":68},[58,470,234],{"class":71},[58,472,473,476,478,481,483],{"class":60,"line":85},[58,474,475],{"class":78},"    EXTRACT(DOW ",[58,477,289],{"class":71},[58,479,480],{"class":78}," created_at) ",[58,482,249],{"class":71},[58,484,485],{"class":78}," day_of_week,\n",[58,487,488,490,492,494,497,499],{"class":60,"line":96},[58,489,257],{"class":179},[58,491,260],{"class":78},[58,493,263],{"class":71},[58,495,496],{"class":78},")                      ",[58,498,249],{"class":71},[58,500,501],{"class":78}," order_count\n",[58,503,504,506],{"class":60,"line":103},[58,505,289],{"class":71},[58,507,292],{"class":78},[58,509,510,512],{"class":60,"line":109},[58,511,412],{"class":71},[58,513,514],{"class":78}," day_of_week\n",[58,516,517,519],{"class":60,"line":120},[58,518,424],{"class":71},[58,520,521],{"class":78}," day_of_week;\n",[58,523,524],{"class":60,"line":125},[58,525,100],{"emptyLinePlaceholder":99},[58,527,528],{"class":60,"line":131},[58,529,530],{"class":64},"-- Orders placed in business hours (9am–5pm)\n",[58,532,533,535,538,540,542,545,547],{"class":60,"line":142},[58,534,72],{"class":71},[58,536,537],{"class":179}," COUNT",[58,539,260],{"class":78},[58,541,263],{"class":71},[58,543,544],{"class":78},") ",[58,546,289],{"class":71},[58,548,292],{"class":78},[58,550,551,553,556,559,562,565,568,571,574,577,579,582,585,588,591],{"class":60,"line":147},[58,552,297],{"class":71},[58,554,555],{"class":78}," EXTRACT(",[58,557,558],{"class":71},"HOUR",[58,560,561],{"class":71}," FROM",[58,563,564],{"class":78}," created_at ",[58,566,567],{"class":71},"AT",[58,569,570],{"class":71}," TIME",[58,572,573],{"class":71}," ZONE",[58,575,576],{"class":242}," 'Europe\u002FLondon'",[58,578,544],{"class":78},[58,580,581],{"class":71},"BETWEEN",[58,583,584],{"class":179}," 9",[58,586,587],{"class":71}," AND",[58,589,590],{"class":179}," 17",[58,592,429],{"class":78},[58,594,595],{"class":60,"line":153},[58,596,100],{"emptyLinePlaceholder":99},[58,598,599],{"class":60,"line":163},[58,600,601],{"class":64},"-- Year-over-year comparison\n",[58,603,604],{"class":60,"line":168},[58,605,234],{"class":71},[58,607,608,611,614,616,619,621],{"class":60,"line":174},[58,609,610],{"class":78},"    EXTRACT(",[58,612,613],{"class":71},"YEAR",[58,615,561],{"class":71},[58,617,618],{"class":78}," created_at)  ",[58,620,249],{"class":71},[58,622,623],{"class":78}," yr,\n",[58,625,626,628,631,633,635,637],{"class":60,"line":402},[58,627,610],{"class":78},[58,629,630],{"class":71},"MONTH",[58,632,561],{"class":71},[58,634,480],{"class":78},[58,636,249],{"class":71},[58,638,639],{"class":78}," mo,\n",[58,641,642,644,647,649],{"class":60,"line":409},[58,643,276],{"class":179},[58,645,646],{"class":78},"(total_amount) ",[58,648,249],{"class":71},[58,650,284],{"class":78},[58,652,653,655],{"class":60,"line":421},[58,654,289],{"class":71},[58,656,292],{"class":78},[58,658,660,662],{"class":60,"line":659},19,[58,661,412],{"class":71},[58,663,664],{"class":78}," yr, mo\n",[58,666,668,670],{"class":60,"line":667},20,[58,669,424],{"class":71},[58,671,672],{"class":78}," yr, mo;\n",[10,674,676],{"id":675},"date-arithmetic-with-intervals","Date arithmetic with intervals",[49,678,680],{"className":51,"code":679,"language":53,"meta":54,"style":54},"-- Orders placed in the last 7 days\nSELECT * FROM orders WHERE created_at >= NOW() - INTERVAL '7 days';\n\n-- Subscriptions expiring in the next 30 days\nSELECT customer_id, plan, expires_at\nFROM subscriptions\nWHERE expires_at BETWEEN NOW() AND NOW() + INTERVAL '30 days';\n\n-- Calculate how many days since each customer's last order\nSELECT\n    customer_id,\n    MAX(created_at)                        AS last_order,\n    NOW() - MAX(created_at)                AS time_since,\n    EXTRACT(DAY FROM NOW() - MAX(created_at)) AS days_since\nFROM orders\nGROUP BY customer_id\nORDER BY days_since DESC;\n",[23,681,682,687,718,722,727,734,741,771,775,780,784,789,802,822,847,853,860],{"__ignoreMap":54},[58,683,684],{"class":60,"line":61},[58,685,686],{"class":64},"-- Orders placed in the last 7 days\n",[58,688,689,691,694,696,699,701,703,705,707,709,711,713,716],{"class":60,"line":68},[58,690,72],{"class":71},[58,692,693],{"class":71}," *",[58,695,561],{"class":71},[58,697,698],{"class":78}," orders ",[58,700,297],{"class":71},[58,702,564],{"class":78},[58,704,303],{"class":71},[58,706,75],{"class":71},[58,708,308],{"class":78},[58,710,311],{"class":71},[58,712,314],{"class":78},[58,714,715],{"class":242},"'7 days'",[58,717,429],{"class":78},[58,719,720],{"class":60,"line":85},[58,721,100],{"emptyLinePlaceholder":99},[58,723,724],{"class":60,"line":96},[58,725,726],{"class":64},"-- Subscriptions expiring in the next 30 days\n",[58,728,729,731],{"class":60,"line":103},[58,730,72],{"class":71},[58,732,733],{"class":78}," customer_id, plan, expires_at\n",[58,735,736,738],{"class":60,"line":109},[58,737,289],{"class":71},[58,739,740],{"class":78}," subscriptions\n",[58,742,743,745,748,750,752,754,757,759,761,764,766,769],{"class":60,"line":120},[58,744,297],{"class":71},[58,746,747],{"class":78}," expires_at ",[58,749,581],{"class":71},[58,751,75],{"class":71},[58,753,308],{"class":78},[58,755,756],{"class":71},"AND",[58,758,75],{"class":71},[58,760,308],{"class":78},[58,762,763],{"class":71},"+",[58,765,314],{"class":78},[58,767,768],{"class":242},"'30 days'",[58,770,429],{"class":78},[58,772,773],{"class":60,"line":125},[58,774,100],{"emptyLinePlaceholder":99},[58,776,777],{"class":60,"line":131},[58,778,779],{"class":64},"-- Calculate how many days since each customer's last order\n",[58,781,782],{"class":60,"line":142},[58,783,234],{"class":71},[58,785,786],{"class":60,"line":147},[58,787,788],{"class":78},"    customer_id,\n",[58,790,791,794,797,799],{"class":60,"line":153},[58,792,793],{"class":179},"    MAX",[58,795,796],{"class":78},"(created_at)                        ",[58,798,249],{"class":71},[58,800,801],{"class":78}," last_order,\n",[58,803,804,807,809,811,814,817,819],{"class":60,"line":163},[58,805,806],{"class":71},"    NOW",[58,808,308],{"class":78},[58,810,311],{"class":71},[58,812,813],{"class":179}," MAX",[58,815,816],{"class":78},"(created_at)                ",[58,818,249],{"class":71},[58,820,821],{"class":78}," time_since,\n",[58,823,824,826,829,831,833,835,837,839,842,844],{"class":60,"line":168},[58,825,610],{"class":78},[58,827,828],{"class":71},"DAY",[58,830,561],{"class":71},[58,832,75],{"class":71},[58,834,308],{"class":78},[58,836,311],{"class":71},[58,838,813],{"class":179},[58,840,841],{"class":78},"(created_at)) ",[58,843,249],{"class":71},[58,845,846],{"class":78}," days_since\n",[58,848,849,851],{"class":60,"line":174},[58,850,289],{"class":71},[58,852,292],{"class":78},[58,854,855,857],{"class":60,"line":402},[58,856,412],{"class":71},[58,858,859],{"class":78}," customer_id\n",[58,861,862,864,867,870],{"class":60,"line":409},[58,863,424],{"class":71},[58,865,866],{"class":78}," days_since ",[58,868,869],{"class":71},"DESC",[58,871,429],{"class":78},[15,873,874,875,39,878,881],{},"MySQL uses ",[23,876,877],{},"DATE_ADD",[23,879,880],{},"DATE_SUB",":",[49,883,885],{"className":51,"code":884,"language":53,"meta":54,"style":54},"SELECT * FROM orders WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);\n",[23,886,887],{"__ignoreMap":54},[58,888,889,891,893,895,897,899,901,903,906,909,912,915,918],{"class":60,"line":61},[58,890,72],{"class":71},[58,892,693],{"class":71},[58,894,561],{"class":71},[58,896,698],{"class":78},[58,898,297],{"class":71},[58,900,564],{"class":78},[58,902,303],{"class":71},[58,904,905],{"class":78}," DATE_SUB(",[58,907,908],{"class":71},"NOW",[58,910,911],{"class":78},"(), INTERVAL ",[58,913,914],{"class":179},"7",[58,916,917],{"class":71}," DAY",[58,919,920],{"class":78},");\n",[15,922,923,924,881],{},"SQL Server uses ",[23,925,926],{},"DATEADD",[49,928,930],{"className":51,"code":929,"language":53,"meta":54,"style":54},"SELECT * FROM orders WHERE created_at >= DATEADD(DAY, -7, GETDATE());\n",[23,931,932],{"__ignoreMap":54},[58,933,934,936,938,940,942,944,946,948,951,953,955,958,960,962,964,967],{"class":60,"line":61},[58,935,72],{"class":71},[58,937,693],{"class":71},[58,939,561],{"class":71},[58,941,698],{"class":78},[58,943,297],{"class":71},[58,945,564],{"class":78},[58,947,303],{"class":71},[58,949,950],{"class":179}," DATEADD",[58,952,260],{"class":78},[58,954,828],{"class":71},[58,956,957],{"class":78},", ",[58,959,311],{"class":71},[58,961,914],{"class":179},[58,963,957],{"class":78},[58,965,966],{"class":179},"GETDATE",[58,968,969],{"class":78},"());\n",[10,971,973],{"id":972},"to_char-format-formatting-for-display","TO_CHAR \u002F FORMAT — formatting for display",[49,975,977],{"className":51,"code":976,"language":53,"meta":54,"style":54},"-- Postgres: format a timestamp as a readable string\nSELECT TO_CHAR(created_at, 'DD Mon YYYY HH24:MI') AS formatted\nFROM orders;\n-- → '20 Jun 2026 14:35'\n\nSELECT TO_CHAR(created_at, 'YYYY-MM') AS month_label FROM orders;\n-- → '2026-06'\n\n-- MySQL: DATE_FORMAT\nSELECT DATE_FORMAT(created_at, '%d %b %Y %H:%i') AS formatted FROM orders;\n\n-- SQL Server: FORMAT\nSELECT FORMAT(created_at, 'dd MMM yyyy HH:mm') AS formatted FROM orders;\n",[23,978,979,984,1001,1008,1013,1017,1037,1042,1046,1051,1075,1079,1084],{"__ignoreMap":54},[58,980,981],{"class":60,"line":61},[58,982,983],{"class":64},"-- Postgres: format a timestamp as a readable string\n",[58,985,986,988,991,994,996,998],{"class":60,"line":68},[58,987,72],{"class":71},[58,989,990],{"class":78}," TO_CHAR(created_at, ",[58,992,993],{"class":242},"'DD Mon YYYY HH24:MI'",[58,995,544],{"class":78},[58,997,249],{"class":71},[58,999,1000],{"class":78}," formatted\n",[58,1002,1003,1005],{"class":60,"line":85},[58,1004,289],{"class":71},[58,1006,1007],{"class":78}," orders;\n",[58,1009,1010],{"class":60,"line":96},[58,1011,1012],{"class":64},"-- → '20 Jun 2026 14:35'\n",[58,1014,1015],{"class":60,"line":103},[58,1016,100],{"emptyLinePlaceholder":99},[58,1018,1019,1021,1023,1026,1028,1030,1033,1035],{"class":60,"line":109},[58,1020,72],{"class":71},[58,1022,990],{"class":78},[58,1024,1025],{"class":242},"'YYYY-MM'",[58,1027,544],{"class":78},[58,1029,249],{"class":71},[58,1031,1032],{"class":78}," month_label ",[58,1034,289],{"class":71},[58,1036,1007],{"class":78},[58,1038,1039],{"class":60,"line":120},[58,1040,1041],{"class":64},"-- → '2026-06'\n",[58,1043,1044],{"class":60,"line":125},[58,1045,100],{"emptyLinePlaceholder":99},[58,1047,1048],{"class":60,"line":131},[58,1049,1050],{"class":64},"-- MySQL: DATE_FORMAT\n",[58,1052,1053,1055,1058,1061,1064,1066,1068,1071,1073],{"class":60,"line":142},[58,1054,72],{"class":71},[58,1056,1057],{"class":71}," DATE_FORMAT",[58,1059,1060],{"class":78},"(created_at, ",[58,1062,1063],{"class":242},"'%d %b %Y %H:%i'",[58,1065,544],{"class":78},[58,1067,249],{"class":71},[58,1069,1070],{"class":78}," formatted ",[58,1072,289],{"class":71},[58,1074,1007],{"class":78},[58,1076,1077],{"class":60,"line":147},[58,1078,100],{"emptyLinePlaceholder":99},[58,1080,1081],{"class":60,"line":153},[58,1082,1083],{"class":64},"-- SQL Server: FORMAT\n",[58,1085,1086,1088,1091,1093,1096,1098,1100,1102,1104],{"class":60,"line":163},[58,1087,72],{"class":71},[58,1089,1090],{"class":179}," FORMAT",[58,1092,1060],{"class":78},[58,1094,1095],{"class":242},"'dd MMM yyyy HH:mm'",[58,1097,544],{"class":78},[58,1099,249],{"class":71},[58,1101,1070],{"class":78},[58,1103,289],{"class":71},[58,1105,1007],{"class":78},[10,1107,1109],{"id":1108},"timezone-handling","Timezone handling",[49,1111,1113],{"className":51,"code":1112,"language":53,"meta":54,"style":54},"-- Convert a UTC timestamp to a specific timezone (Postgres)\nSELECT\n    created_at                                        AS utc_time,\n    created_at AT TIME ZONE 'Europe\u002FLondon'           AS london_time,\n    created_at AT TIME ZONE 'America\u002FNew_York'        AS new_york_time\nFROM orders LIMIT 5;\n\n-- Store all timestamps in UTC; convert at query time\n-- Never store local time in TIMESTAMPTZ — the database converts it for you\n\n-- Find orders placed during peak London hours\nSELECT COUNT(*) FROM orders\nWHERE (created_at AT TIME ZONE 'Europe\u002FLondon')::TIME\n      BETWEEN '09:00' AND '17:00';\n",[23,1114,1115,1120,1124,1134,1153,1172,1186,1190,1195,1200,1204,1209,1225,1246],{"__ignoreMap":54},[58,1116,1117],{"class":60,"line":61},[58,1118,1119],{"class":64},"-- Convert a UTC timestamp to a specific timezone (Postgres)\n",[58,1121,1122],{"class":60,"line":68},[58,1123,234],{"class":71},[58,1125,1126,1129,1131],{"class":60,"line":85},[58,1127,1128],{"class":78},"    created_at                                        ",[58,1130,249],{"class":71},[58,1132,1133],{"class":78}," utc_time,\n",[58,1135,1136,1139,1141,1143,1145,1147,1150],{"class":60,"line":96},[58,1137,1138],{"class":78},"    created_at ",[58,1140,567],{"class":71},[58,1142,570],{"class":71},[58,1144,573],{"class":71},[58,1146,576],{"class":242},[58,1148,1149],{"class":71},"           AS",[58,1151,1152],{"class":78}," london_time,\n",[58,1154,1155,1157,1159,1161,1163,1166,1169],{"class":60,"line":103},[58,1156,1138],{"class":78},[58,1158,567],{"class":71},[58,1160,570],{"class":71},[58,1162,573],{"class":71},[58,1164,1165],{"class":242}," 'America\u002FNew_York'",[58,1167,1168],{"class":71},"        AS",[58,1170,1171],{"class":78}," new_york_time\n",[58,1173,1174,1176,1178,1181,1184],{"class":60,"line":109},[58,1175,289],{"class":71},[58,1177,698],{"class":78},[58,1179,1180],{"class":71},"LIMIT",[58,1182,1183],{"class":179}," 5",[58,1185,429],{"class":78},[58,1187,1188],{"class":60,"line":120},[58,1189,100],{"emptyLinePlaceholder":99},[58,1191,1192],{"class":60,"line":125},[58,1193,1194],{"class":64},"-- Store all timestamps in UTC; convert at query time\n",[58,1196,1197],{"class":60,"line":131},[58,1198,1199],{"class":64},"-- Never store local time in TIMESTAMPTZ — the database converts it for you\n",[58,1201,1202],{"class":60,"line":142},[58,1203,100],{"emptyLinePlaceholder":99},[58,1205,1206],{"class":60,"line":147},[58,1207,1208],{"class":64},"-- Find orders placed during peak London hours\n",[58,1210,1211,1213,1215,1217,1219,1221,1223],{"class":60,"line":153},[58,1212,72],{"class":71},[58,1214,537],{"class":179},[58,1216,260],{"class":78},[58,1218,263],{"class":71},[58,1220,544],{"class":78},[58,1222,289],{"class":71},[58,1224,292],{"class":78},[58,1226,1227,1229,1232,1234,1236,1238,1240,1243],{"class":60,"line":163},[58,1228,297],{"class":71},[58,1230,1231],{"class":78}," (created_at ",[58,1233,567],{"class":71},[58,1235,570],{"class":71},[58,1237,573],{"class":71},[58,1239,576],{"class":242},[58,1241,1242],{"class":78},")::",[58,1244,1245],{"class":71},"TIME\n",[58,1247,1248,1251,1254,1256,1259],{"class":60,"line":168},[58,1249,1250],{"class":71},"      BETWEEN",[58,1252,1253],{"class":242}," '09:00'",[58,1255,587],{"class":71},[58,1257,1258],{"class":242}," '17:00'",[58,1260,429],{"class":78},[10,1262,1264],{"id":1263},"age-and-datediff-time-elapsed","AGE and DATEDIFF — time elapsed",[49,1266,1268],{"className":51,"code":1267,"language":53,"meta":54,"style":54},"-- Postgres: AGE returns an interval\nSELECT customer_id, AGE(NOW(), created_at) AS account_age FROM customers;\n-- → '1 year 3 mons 15 days'\n\nSELECT EXTRACT(YEAR FROM AGE(birthdate)) AS age_years FROM users;\n\n-- MySQL: TIMESTAMPDIFF\nSELECT TIMESTAMPDIFF(DAY, created_at, NOW()) AS days_old FROM orders;\n\n-- SQL Server: DATEDIFF\nSELECT DATEDIFF(DAY, created_at, GETDATE()) AS days_old FROM orders;\n",[23,1269,1270,1275,1297,1302,1306,1329,1333,1338,1364,1368,1373],{"__ignoreMap":54},[58,1271,1272],{"class":60,"line":61},[58,1273,1274],{"class":64},"-- Postgres: AGE returns an interval\n",[58,1276,1277,1279,1282,1284,1287,1289,1292,1294],{"class":60,"line":68},[58,1278,72],{"class":71},[58,1280,1281],{"class":78}," customer_id, AGE(",[58,1283,908],{"class":71},[58,1285,1286],{"class":78},"(), created_at) ",[58,1288,249],{"class":71},[58,1290,1291],{"class":78}," account_age ",[58,1293,289],{"class":71},[58,1295,1296],{"class":78}," customers;\n",[58,1298,1299],{"class":60,"line":85},[58,1300,1301],{"class":64},"-- → '1 year 3 mons 15 days'\n",[58,1303,1304],{"class":60,"line":96},[58,1305,100],{"emptyLinePlaceholder":99},[58,1307,1308,1310,1312,1314,1316,1319,1321,1324,1326],{"class":60,"line":103},[58,1309,72],{"class":71},[58,1311,555],{"class":78},[58,1313,613],{"class":71},[58,1315,561],{"class":71},[58,1317,1318],{"class":78}," AGE(birthdate)) ",[58,1320,249],{"class":71},[58,1322,1323],{"class":78}," age_years ",[58,1325,289],{"class":71},[58,1327,1328],{"class":78}," users;\n",[58,1330,1331],{"class":60,"line":109},[58,1332,100],{"emptyLinePlaceholder":99},[58,1334,1335],{"class":60,"line":120},[58,1336,1337],{"class":64},"-- MySQL: TIMESTAMPDIFF\n",[58,1339,1340,1342,1345,1347,1350,1352,1355,1357,1360,1362],{"class":60,"line":125},[58,1341,72],{"class":71},[58,1343,1344],{"class":78}," TIMESTAMPDIFF(",[58,1346,828],{"class":71},[58,1348,1349],{"class":78},", created_at, ",[58,1351,908],{"class":71},[58,1353,1354],{"class":78},"()) ",[58,1356,249],{"class":71},[58,1358,1359],{"class":78}," days_old ",[58,1361,289],{"class":71},[58,1363,1007],{"class":78},[58,1365,1366],{"class":60,"line":131},[58,1367,100],{"emptyLinePlaceholder":99},[58,1369,1370],{"class":60,"line":142},[58,1371,1372],{"class":64},"-- SQL Server: DATEDIFF\n",[58,1374,1375,1377,1380,1382,1384,1386,1388,1390,1392,1394,1396],{"class":60,"line":147},[58,1376,72],{"class":71},[58,1378,1379],{"class":179}," DATEDIFF",[58,1381,260],{"class":78},[58,1383,828],{"class":71},[58,1385,1349],{"class":78},[58,1387,966],{"class":179},[58,1389,1354],{"class":78},[58,1391,249],{"class":71},[58,1393,1359],{"class":78},[58,1395,289],{"class":71},[58,1397,1007],{"class":78},[10,1399,1401],{"id":1400},"recap","Recap",[15,1403,1404,1405,1407,1408,1411,1412,1414,1415,1417,1418,1421,1422,39,1425,1428,1429,1431],{},"Store timestamps as ",[23,1406,25],{}," and always in UTC — let the database convert\nto local time at query time with ",[23,1409,1410],{},"AT TIME ZONE",". Use ",[23,1413,218],{}," to group by\ntime period for reports and charts. Use ",[23,1416,455],{}," to filter by time component\n(hour of day, day of week). Use ",[23,1419,1420],{},"INTERVAL"," arithmetic for relative date ranges\nrather than hardcoding date strings. Format timestamps for display with\n",[23,1423,1424],{},"TO_CHAR",[23,1426,1427],{},"DATE_FORMAT"," only in the final ",[23,1430,72],{}," — keep date arithmetic\nin native date types, not strings.",[1433,1434,1435],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":54,"searchDepth":68,"depth":68,"links":1437},[1438,1439,1440,1441,1442,1443,1444,1445,1446],{"id":12,"depth":68,"text":13},{"id":46,"depth":68,"text":47},{"id":212,"depth":68,"text":213},{"id":449,"depth":68,"text":450},{"id":675,"depth":68,"text":676},{"id":972,"depth":68,"text":973},{"id":1108,"depth":68,"text":1109},{"id":1263,"depth":68,"text":1264},{"id":1400,"depth":68,"text":1401},"SQL date and time functions with real examples — NOW, CURRENT_DATE, DATE_TRUNC, EXTRACT, date arithmetic, TO_CHAR, and timezone handling.","medium","md","SQL",{},"\u002Fblog\u002Fsql-date-time-functions","\u002Fsql\u002Ffunctions\u002Fdate-functions",{"title":5,"description":1447},"blog\u002Fsql-date-time-functions","Date & Time Functions","Built-in Functions","functions","2026-06-20","2rYDH4z675Ze-uRrZTQKxHv050bwugjbqVMTkrX4PFc",1782244088438]