Every once and awhile, I always stumble with the problem of parsing/formatting DateTime. This happens in MySQL, Oracle DB, MS SQL and .NET environment (yeah, my company has all of them :D)
Since I often forget about them, let me just put it down here for my (hopefully, yours too) quick reference in the future.
In MySQL, converting DateTime to String is using DATE_FORMAT function. On the other hand, parsing String to DateTime is using STR_TO_DATE.
SELECT DATE_FORMAT(NOW(), '%d-%M-%Y'); -- Output: 21-March-2015 SELECT STR_TO_DATE('19-February-2015', '%d-%M-%Y'); -- Output: 2015-02-19
The complete list of symbols which can be used is listed below (prettified, original source can be found HERE):
Specifier | Description |
---|---|
%a | Abbreviated weekday name (Sun..Sat) |
%b | Abbreviated month name (Jan..Dec) |
%c | Month, numeric (0..12) |
%D | Day of the month with English suffix (0th, 1st, 2nd, 3rd, …) |
%d | Day of the month, numeric (00..31) |
%e | Day of the month, numeric (0..31) |
%f | Microseconds (000000..999999) |
%H | Hour (00..23) |
%h | Hour (01..12) |
%I | Hour (01..12) |
%i | Minutes, numeric (00..59) |
%j | Day of year (001..366) |
%k | Hour (0..23) |
%l | Hour (1..12) |
%M | Month name (January..December) |
%m | Month, numeric (00..12) |
%p | AM or PM |
%r | Time, 12-hour (hh:mm:ss followed by AM or PM) |
%S | Seconds (00..59) |
%s | Seconds (00..59) |
%T | Time, 24-hour (hh:mm:ss) |
%U | Week (00..53), where Sunday is the first day of the week; WEEK() mode 0 |
%u | Week (00..53), where Monday is the first day of the week; WEEK() mode 1 |
%V | Week (01..53), where Sunday is the first day of the week; WEEK() mode 2; used with %X |
%v | Week (01..53), where Monday is the first day of the week; WEEK() mode 3; used with %x |
%W | Weekday name (Sunday..Saturday) |
%w | Day of the week (0=Sunday..6=Saturday) |
%X | Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V |
%x | Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v |
%Y | Year, numeric, four digits |
%y | Year, numeric (two digits) |
%% | A literal “%” character |
%x | x, for any “x” not listed above |
In Oracle, converting DateTime to String is using TO_CHAR function. As for parsing String to DateTime, we use TO_DATE.
SELECT TO_CHAR(current_timestamp, 'DD-MON-YYYY') from dual; -- Output: 21-March-2015 SELECT TO_DATE('19-FEB-2015', 'DD-MON-YYYY') from dual; -- Output: 19-FEB-15
The complete list of symbols that can be used are listed below (prettified, original source can be found HERE):
Element | Specify in TO_* datetime functions? | Description |
---|---|---|
- / , . ; : "text" | Yes | Punctuation and quoted text is reproduced in the result. |
AD A.D. | Yes | AD indicator with or without periods. |
AM A.M. | Yes | Meridian indicator with or without periods. |
BC B.C. | Yes | BC indicator with or without periods. |
CC SCC | No | Century.
For example, 2002 returns 21; 2000 returns 20. |
D | Yes | Day of week (1-7). |
DAY | Yes | Name of day, padded with blanks to display width of the widest name of day in the date language used for this element. |
DD | Yes | Day of month (1-31). |
DDD | Yes | Day of year (1-366). |
DL | Yes | Returns a value in the long date format, which is an extension of Oracle Database’s DATE format (the current value of the NLS_DATE_FORMAT parameter). Makes the appearance of the date components (day name, month number, and so forth) depend on the NLS_TERRITORY and NLS_LANGUAGE parameters. For example, in the AMERICAN_AMERICA locale, this is equivalent to specifying the format ‘fmDay, Month dd, yyyy’. In the GERMAN_GERMANY locale, it is equivalent to specifying the format ‘fmDay, dd. Month yyyy’. Restriction: You can specify this format only with the TS element, separated by white space. |
DS | Yes | Returns a value in the short date format. Makes the appearance of the date components (day name, month number, and so forth) depend on the NLS_TERRITORY and NLS_LANGUAGE parameters. For example, in the AMERICAN_AMERICA locale, this is equivalent to specifying the format ‘MM/DD/RRRR’. In the ENGLISH_UNITED_KINGDOM locale, it is equivalent to specifying the format ‘DD/MM/RRRR’. Restriction: You can specify this format only with the TS element, separated by white space. |
DY | Yes | Abbreviated name of day. |
E | No | Abbreviated era name (Japanese Imperial, ROC Official, and Thai Buddha calendars). |
EE | No | Full era name (Japanese Imperial, ROC Official, and Thai Buddha calendars). |
FF [1..9] | Yes | Fractional seconds; no radix character is printed (use the X format element to add the radix character). Use the numbers 1 to 9 after FF to specify the number of digits in the fractional second portion of the datetime value returned. If you do not specify a digit, then Oracle Database uses the precision specified for the datetime datatype or the datatype’s default precision. Examples: ‘HH:MI:SS.FF’ SELECT TO_CHAR(SYSTIMESTAMP, 'SS.FF3') from dual; |
FM | Yes | Returns a value with no leading or trailing blanks. |
FX | Yes | Requires exact matching between the character data and the format model. |
HH | Yes | Hour of day (1-12). |
HH12 | No | Hour of day (1-12). |
HH24 | Yes | Hour of day (0-23). |
IW | No | Week of year (1-52 or 1-53) based on the ISO standard. |
IYY IY I | No | Last 3, 2, or 1 digit(s) of ISO year. |
IYYY | No | 4-digit year based on the ISO standard. |
J | Yes | Julian day; the number of days since January 1, 4712 BC. Number specified with J must be integers. |
MI | Yes | Minute (0-59). |
MM | Yes | Month (01-12; January = 01). |
MON | Yes | Abbreviated name of month. |
MONTH | Yes | Name of month, padded with blanks to display width of the widest name of month in the date language used for this element. |
PM P.M. | No | Meridian indicator with or without periods. |
Q | No | Quarter of year (1, 2, 3, 4; January – March = 1). |
RM | Yes | Roman numeral month (I-XII; January = I). |
RR | Yes | Lets you store 20th century dates in the 21st century using only two digits. |
RRRR | Yes | Round year. Accepts either 4-digit or 2-digit input. If 2-digit, provides the same return as RR. If you do not want this functionality, then enter the 4-digit year. |
SS | Yes | Second (0-59). |
SSSSS | Yes | Seconds past midnight (0-86399). |
TS | Yes | Returns a value in the short time format. Makes the appearance of the time components (hour, minutes, and so forth) depend on the NLS_TERRITORY and NLS_LANGUAGE initialization parameters. Restriction: You can specify this format only with the DL or DS element, separated by white space. |
TZD | Yes | Daylight savings information. The TZD value is an abbreviated time zone string with daylight savings information. It must correspond with the region specified in TZR. Example: PST (for US/Pacific standard time); PDT (for US/Pacific daylight time). |
TZH | Yes | Time zone hour. (See TZM format element.) Example: ‘HH:MI:SS.FFTZH:TZM’. |
TZM | Yes | Time zone minute. (See TZH format element.) Example: ‘HH:MI:SS.FFTZH:TZM’. |
TZR | Yes | Time zone region information. The value must be one of the time zone regions supported in the database. Example: US/Pacific |
WW | No | Week of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year. |
W | No | Week of month (1-5) where week 1 starts on the first day of the month and ends on the seventh. |
X | Yes | Local radix character. Example: ‘HH:MI:SSXFF’. |
Y,YYY | Yes | Year with comma in this position. |
YEAR SYEAR | No | Year, spelled out; S prefixes BC dates with a minus sign (-). |
YYYY SYYYY | Yes | 4-digit year; S prefixes BC dates with a minus sign. |
YYY YY Y | Yes | Last 3, 2, or 1 digit(s) of year. |
In MS SQL, converting DateTime to String is using FORMAT function. To convert from String to DateTime, we can use either CONVERT or PARSE.
Unfortunately, we can’t really use custom format to parse a string.To make things easy to remember, I simplified it to two ways:
- The German way.
- Culture code: de-DE
- Culture mode (with millenia): 104
- Culture mode (without millenia): 4
- DateTime format: dd-MM-yyyy (date before month)
- The US way.
- Culture code: en-US
- Culture mode: 101
- Culture mode (without millenia): 1
- DateTime format: MM-dd-yyyy (month before date)
select FORMAT(CURRENT_TIMESTAMP,'dd-MMM-yyyy'); --Output: 21-Mar-2015 -- The US Way, with millenia select convert(datetime, '03-06-2012 10:11', 101); --Output: 2012-03-06 10:11:00.000 -- The US Way, without millenia select convert(datetime, '03-06-12 10:11', 1); --Output: 2012-03-06 10:11:00.000 -- The German way select PARSE('03.06.2012 19:00' as datetime using 'de-DE'); select PARSE('03/06/2012 19:00' as datetime using 'de-DE'); select PARSE('03-06-2012 19:00' as datetime using 'de-DE'); -- All three has the same output: 2012-06-03 19:00:00.000
Other symbols that can be used in formatting a datetime are shown below (prettified, original source can be find HERE):
Format specifier | Description | Examples |
---|---|---|
d | The day of the month, from 1 through 31. | 2009-06-01T13:45:30 -> 1 2009-06-15T13:45:30 -> 15 |
dd | The day of the month, from 01 through 31. | 2009-06-01T13:45:30 -> 01 2009-06-15T13:45:30 -> 15 |
ddd | The abbreviated name of the day of the week. | 2009-06-15T13:45:30 -> Mon (en-US) 2009-06-15T13:45:30 -> ?? (ru-RU) 2009-06-15T13:45:30 -> lun. (fr-FR) |
dddd | The full name of the day of the week. | 2009-06-15T13:45:30 -> Monday (en-US) 2009-06-15T13:45:30 -> ??????????? (ru-RU) 2009-06-15T13:45:30 -> lundi (fr-FR) |
f | The tenths of a second in a date and time value. | 2009-06-15T13:45:30.6170000 -> 6 2009-06-15T13:45:30.05 -> 0 |
ff | The hundredths of a second in a date and time value. | 2009-06-15T13:45:30.6170000 -> 61 2009-06-15T13:45:30.0500000 -> 00 |
fff | The milliseconds in a date and time value. | 6/15/2009 13:45:30.617 -> 617 6/15/2009 13:45:30.0005 -> 000 |
ffff | The ten thousandths of a second in a date and time value. | 2009-06-15T13:45:30.6175000 -> 6175 2009-06-15T13:45:30.0000500 -> 0000 |
fffff | The hundred thousandths of a second in a date and time value. | 2009-06-15T13:45:30.6175400 -> 61754 6/15/2009 13:45:30.000005 -> 00000 |
ffffff | The millionths of a second in a date and time value. | 2009-06-15T13:45:30.6175420 -> 617542 2009-06-15T13:45:30.0000005 -> 000000 |
fffffff | The ten millionths of a second in a date and time value. | 2009-06-15T13:45:30.6175425 -> 6175425 2009-06-15T13:45:30.0001150 -> 0001150 |
F | If non-zero, the tenths of a second in a date and time value. | 2009-06-15T13:45:30.6170000 -> 6 2009-06-15T13:45:30.0500000 -> (no output) |
FF | If non-zero, the hundredths of a second in a date and time value. | 2009-06-15T13:45:30.6170000 -> 61 2009-06-15T13:45:30.0050000 -> (no output) |
FFF | If non-zero, the milliseconds in a date and time value. | 2009-06-15T13:45:30.6170000 -> 617 2009-06-15T13:45:30.0005000 -> (no output) |
FFFF | If non-zero, the ten thousandths of a second in a date and time value. | 2009-06-15T13:45:30.5275000 -> 5275 2009-06-15T13:45:30.0000500 -> (no output) |
FFFFF | If non-zero, the hundred thousandths of a second in a date and time value. | 2009-06-15T13:45:30.6175400 -> 61754 2009-06-15T13:45:30.0000050 -> (no output) |
FFFFFF | If non-zero, the millionths of a second in a date and time value. | 2009-06-15T13:45:30.6175420 -> 617542 2009-06-15T13:45:30.0000005 -> (no output) |
FFFFFFF | If non-zero, the ten millionths of a second in a date and time value. | 2009-06-15T13:45:30.6175425 -> 6175425 2009-06-15T13:45:30.0001150 -> 000115 |
g gg | The period or era. | 2009-06-15T13:45:30.6170000 -> A.D. |
h | The hour, using a 12-hour clock from 1 to 12. | 2009-06-15T01:45:30 -> 1 2009-06-15T13:45:30 -> 1 |
hh | The hour, using a 12-hour clock from 01 to 12. | 2009-06-15T01:45:30 -> 01 2009-06-15T13:45:30 -> 01 |
H | The hour, using a 24-hour clock from 0 to 23. | 2009-06-15T01:45:30 -> 1 2009-06-15T13:45:30 -> 13 |
HH | The hour, using a 24-hour clock from 00 to 23. | 2009-06-15T01:45:30 -> 01 2009-06-15T13:45:30 -> 13 |
K | Time zone information. | With DateTime values: 2009-06-15T13:45:30, Kind Unspecified -> 2009-06-15T13:45:30, Kind Utc -> Z 2009-06-15T13:45:30, Kind Local -> -07:00 (depends on local computer settings) With DateTimeOffset values: 2009-06-15T01:45:30-07:00 –> -07:00 2009-06-15T08:45:30+00:00 –> +00:00 |
m | The minute, from 0 through 59. | 2009-06-15T01:09:30 -> 9 2009-06-15T13:29:30 -> 29 |
mm | The minute, from 00 through 59. | 2009-06-15T01:09:30 -> 09 2009-06-15T01:45:30 -> 45 |
M | The month, from 1 through 12. | 2009-06-15T13:45:30 -> 6 |
MM | The month, from 01 through 12. | 2009-06-15T13:45:30 -> 06 |
MMM | The abbreviated name of the month. | 2009-06-15T13:45:30 -> Jun (en-US) 2009-06-15T13:45:30 -> juin (fr-FR) 2009-06-15T13:45:30 -> Jun (zu-ZA) |
MMMM | The full name of the month. | 2009-06-15T13:45:30 -> June (en-US) 2009-06-15T13:45:30 -> juni (da-DK) 2009-06-15T13:45:30 -> uJuni (zu-ZA) |
s | The second, from 0 through 59. | 2009-06-15T13:45:09 -> 9 |
ss | The second, from 00 through 59. | 2009-06-15T13:45:09 -> 09 |
t | The first character of the AM/PM designator. | 2009-06-15T13:45:30 -> P (en-US) 2009-06-15T13:45:30 -> ? (ja-JP) 2009-06-15T13:45:30 -> (fr-FR) |
tt | The AM/PM designator. | 2009-06-15T13:45:30 -> PM (en-US) 2009-06-15T13:45:30 -> ?? (ja-JP) 2009-06-15T13:45:30 -> (fr-FR) |
y | The year, from 0 to 99. | 0001-01-01T00:00:00 -> 1 0900-01-01T00:00:00 -> 0 1900-01-01T00:00:00 -> 0 2009-06-15T13:45:30 -> 9 2019-06-15T13:45:30 -> 19 |
yy | The year, from 00 to 99. | 0001-01-01T00:00:00 -> 01 0900-01-01T00:00:00 -> 00 1900-01-01T00:00:00 -> 00 2019-06-15T13:45:30 -> 19 |
yyy | The year, with a minimum of three digits. | 0001-01-01T00:00:00 -> 001 0900-01-01T00:00:00 -> 900 1900-01-01T00:00:00 -> 1900 2009-06-15T13:45:30 -> 2009 |
yyyy | The year as a four-digit number. | 0001-01-01T00:00:00 -> 0001 0900-01-01T00:00:00 -> 0900 1900-01-01T00:00:00 -> 1900 2009-06-15T13:45:30 -> 2009 |
yyyyy | The year as a five-digit number. | 0001-01-01T00:00:00 -> 00001 2009-06-15T13:45:30 -> 02009 |
z | Hours offset from UTC, with no leading zeros. | 2009-06-15T13:45:30-07:00 -> -7 |
zz | Hours offset from UTC, with a leading zero for a single-digit value. | 2009-06-15T13:45:30-07:00 -> -07 |
zzz | Hours and minutes offset from UTC. | 2009-06-15T13:45:30-07:00 -> -07:00 |
: | The time separator. | 2009-06-15T13:45:30 -> : (en-US) 2009-06-15T13:45:30 -> . (it-IT) 2009-06-15T13:45:30 -> : (ja-JP) |
/ | The date separator. | 2009-06-15T13:45:30 -> / (en-US) 2009-06-15T13:45:30 -> – (ar-DZ) 2009-06-15T13:45:30 -> . (tr-TR) |
“string” ‘string’ | Literal string delimiter. | 2009-06-15T13:45:30 (“arr:” h:m t) -> arr: 1:45 P 2009-06-15T13:45:30 (‘arr:’ h:m t) -> arr: 1:45 P |
% | Defines the following character as a custom format specifier. | 2009-06-15T13:45:30 (%h) -> 1 |
\ | The escape character. | 2009-06-15T13:45:30 (h \h) -> 1 h |
Any other character | The character is copied to the result string unchanged. | 2009-06-15T01:45:30 (arr hh:mm t) -> arr 01:45 A |
By .NET Framework I mean C# :D. In C#, converting a DateTime object to a String is by calling its ToString method. On the other hand, converting a String to a DateTime is by using either DateTime.Parse or DateTime.ParseExact.
Console.WriteLine(DateTime.Now.ToString()); // Output: 3/21/2015 5:50:43 AM Console.WriteLine(DateTime.Now.ToString("dd-MMM-yyyy")); // Output: 21-Mar-2015 var dt = DateTime.Parse("19 Mar 2012"); // Works var dt1 = DateTime.Parse("19 03 2012"); // Exception, because my default the US Way var dt2 = DateTime.Parse("03 19 2012"); // Only works if your default culture has date format similar to German, e.g. Italy // Now we parse with custom format var dt3 = DateTime.ParseExact("19 03 2012", "dd MM yyyy", System.Globalization.CultureInfo.InvariantCulture) // Works
As we can see, we may pass the custom format to DateTime.ParseExact and DateTime.ToString. The symbols which we can use in the custom format is exactly the same as the symbols we use in MS SQL (please refer to the previous page).
Hopefully, converting between DateTime to String, vice-versa, would no longer a problem. You can always return here for a quick reference.
I hope it helps,
Cheers