When generating date formats from a template with Foundation's DateFormatter for the Locale "de", like this:
let locale: Locale = Locale(identifier: "de")
let format = DateFormatter.dateFormat(fromTemplate: "dMMMyGhhmmss",
options: 0,
locale: locale)
I always get this format:
d. MMM y G, h:mm:ss a
which renders
17. Nov. 2018 n. Chr., 8:30:20 PM
The 'PM' part is unusual for Locale "de", but it is my understanding that this method also takes user preferences into account. Is that correct?
I played around with the settings in System Preferences, e.g. switching to 24-hour clock, but nothing I changed had any effect. Do I have to restart something for the changes to take effect?
Can someone explain to me what's going on?
If you use h or H in the template, the format will contain the specified hour format (12-hour or 24-hour), regardless of the locale. Use j instead. This symbol requests the preferred hour format for the locale.
For example, given the template dMMMyGjjmmss, I get:
MMM d, y G, h:mm:ss a (12-hour format) for locale "en"
d. MMM y G, HH:mm:ss (24-hour format) for locale "de"
Apple's documentation states:
The format string uses the format patterns from the Unicode Technical Standard #35.
The Unicode Technical Standard #35 has this to say about the symbol j:
This is a special-purpose symbol. It must not occur in pattern or skeleton data. Instead, it is reserved for use in skeletons passed to APIs doing flexible date pattern generation. In such a context, it requests the preferred hour format for the locale (h, H, K, or k), as determined by whether h, H, K, or k is used in the standard short time format for the locale. In the implementation of such an API, 'j' must be replaced by h, H, K, or k before beginning a match against availableFormats data. Note that use of 'j' in a skeleton passed to an API is the only way to have a skeleton request a locale's preferred time cycle type (12-hour or 24-hour).
Related
What standard called for the use of HH:mm as the 24-hour clock whereas hh:mm is the 12-hour clock?
Likewise, I also often see dates noted as MM/dd/yyyy where MM is in caps to distinguish it from mm which indicates minutes.
Does anyone know what standard this nomenclature is based upon?
Probably you refer to the CLDR project which has defined the LDML standard. LDML means: "Locale Data Markup Language" and is listed as "Unicode Technical Standard #35", see also the title of the linked document:
http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
However, you have not told exactly which language or library you use. Be aware of subtile differences. For example in Java, the old class SimpleDateFormat has exceptionally used the pattern symbol "u" as "Day number of week" while CLDR (and the newer class DateTimeFormatter) really interpretes "u" as "extended year (without era)".
By the way, I would never use "hh:mm" without "a" (as marker for am/pm in English speaking countries) or "B" for day periods (if your library supports it) because otherwise the 12-hour-clock is ambivalent.
The DateTimeFormatter class documentation says about its formatting codes for the year:
u year year 2004; 04
y year-of-era year 2004; 04
…
Year: The count of letters determines the minimum field width below which padding is used. If the count of letters is two, then a reduced two digit form is used. For printing, this outputs the rightmost two digits. For parsing, this will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive. If the count of letters is less than four (but not two), then the sign is only output for negative years as per SignStyle.NORMAL. Otherwise, the sign is output if the pad width is exceeded, as per SignStyle.EXCEEDS_PAD.
No other mention of “era”.
So what is the difference between these two codes, u versus y, year versus year-of-era?
When should I use something like this pattern uuuu-MM-dd and when yyyy-MM-dd when working with dates in Java?
Seems that example code written by those in the know use uuuu, but why?
Other formatting classes such as the legacy SimpleDateFormat have only yyyy, so I am confused why java.time brings this uuuu for “year of era”.
Within the scope of java.time-package, we can say:
It is safer to use "u" instead of "y" because DateTimeFormatter will otherwise insist on having an era in combination with "y" (= year-of-era). So using "u" would avoid some possible unexpected exceptions in strict formatting/parsing. See also this SO-post. Another minor thing which is improved by "u"-symbol compared with "y" is printing/parsing negative gregorian years (in far past).
Otherwise we can clearly state that using "u" instead of "y" breaks long-standing habits in Java-programming. It is also not intuitively clear that "u" denotes any kind of year because a) the first letter of the English word "year" is not in agreement with this symbol and b) SimpleDateFormat has used "u" for a different purpose since Java-7 (ISO-day-number-of-week). Confusion is guaranteed - for ever?
We should also see that using eras (symbol "G") in context of ISO is in general dangerous if we consider historic dates. If "G" is used with "u" then both fields are unrelated to each other. And if "G" is used with "y" then the formatter is satisfied but still uses proleptic gregorian calendar when the historic date mandates different calendars and date-handling.
Background information:
When developing and integrating the JSR 310 (java.time-packages) the designers decided to use Common Locale Data Repository (CLDR)/LDML-spec as the base of pattern symbols in DateTimeFormatter. The symbol "u" was already defined in CLDR as proleptic gregorian year, so this meaning was adopted to new upcoming JSR-310 (but not to SimpleDateFormat because of backwards compatibility reasons).
However, this decision to follow CLDR was not quite consistent because JSR-310 had also introduced new pattern symbols which didn't and still don't exist in CLDR, see also this old CLDR-ticket. The suggested symbol "I" was changed by CLDR to "VV" and finally overtaken by JSR-310, including new symbols "x" and "X". But "n" and "N" still don't exist in CLDR, and since this old ticket is closed, it is not clear at all if CLDR will ever support it in the sense of JSR-310. Furthermore, the ticket does not mention the symbol "p" (padding instruction in JSR-310, but not defined in CLDR). So we have still no perfect agreement between pattern definitions across different libraries and languages.
And about "y": We should also not overlook the fact that CLDR associates this year-of-era with at least some kind of mixed Julian/Gregorian year and not with the proleptic gregorian year as JSR-310 does (leaving the oddity of negative years aside). So no perfect agreement between CLDR and JSR-310 here, too.
In the javadoc section Patterns for Formatting and Parsing for DateTimeFormatter it lists the following 3 relevant symbols:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
Just for comparison, these other symbols are easy enough to understand:
D day-of-year number 189
d day-of-month number 10
E day-of-week text Tue; Tuesday; T
The day-of-year, day-of-month, and day-of-week are obviously the day within the given scope (year, month, week).
So, year-of-era means the year within the given scope (era), and right above it era is shown with an example value of AD (the other value of course being BC).
year is the signed year, where year 0 is 1 BC, year -1 is 2 BC, and so forth.
To illustrate: When was Julius Caesar assassinated?
March 15, 44 BC (using pattern MMMM d, y GG)
March 15, -43 (using pattern MMMM d, u)
The distinction will of course only matter if year is zero or negative, and since that is rare, most people don't care, even though they should.
Conclusion: If you use y you should also use G. Since G is rarely used, the correct year symbol is u, not y, otherwise a non-positive year will show incorrectly.
This is known as defensive programming:
Defensive programming is a form of defensive design intended to ensure the continuing function of a piece of software under unforeseen circumstances.
Note that DateTimeFormatter is consistent with SimpleDateFormat:
Letter Date or Time Component Presentation Examples
------ ---------------------- ------------ --------
G Era designator Text AD
y Year Year 1996; 96
Negative years has always been a problem, and they now fixed it by adding u.
Long story short
For 99 % of purposes you can toss a coin, it will make no difference whether you use yyyy or uuuu (or whether you use yy or uu for 2-digit year).
It depends on what you want to happen in case a year earlier than 1 CE (1 AD) occurs. The point being that in 99 % of programs such a year will never occur.
Two other answers have already presented the facts of how u and y work very nicely, but I still felt something was missing, so I am contributing the slightly more opinion-based answer.
For formatting
Assuming that you don’t expect a year before 1 CE to be formatted, the best thing you can do is to check this assumption and react appropriately in case it breaks. For example, depending on circumstances and requirements, you may print an error message or throw an exception. One very soft failure path might be to use a pattern with y (year of era) and G (era) in this case and a pattern with either u or y in the normal, current era case. Note that if you are printing the current date or the date your program was compiled, you can be sure that it is in the common era and may opt to skip the check.
For parsing
In many (most?) cases parsing also means validating meaning you have no guarantees what your input string looks like. Typically it comes from the user or from another system. An example: a date string comes as 2018-09-29. Here the choice between uuuu and yyyy should depend on what you want to happen in case the string contains a year of 0 or negative (e.g., 0000-08-17 or -012-11-13). Assuming that this would be an error, the immediate answer is: use yyyy in order for an exception to be thrown in this case. Still finer: use uuuu and after parsing perform a range check of the parsed date. The latter approach allows both for a finer validation and for a better error message in case of a validation error.
Special case (already mentioned by Meno Hochschild): If your formatter uses strict resolver style and contains y without G, parsing will always fail because strictly speaking year of era is ambiguous without era: 1950 might mean 1950 CE or 1950 BCE (1950 BC). So in this case you need u (or supplying a default era, this is possible through a DateTimeFormatterBuilder).
Long story short again
Explicit range check of your dates, specifically your years, is better than relying on the choice between uuuu and yyyy for catching unexpected very early years.
Short comparison, if you need strict parsing:
Examples with invalid Date 31.02.2022
System.out.println(DateTimeFormatter.ofPattern("dd.MM.yyyy").withResolverStyle(ResolverStyle.STRICT).parse("31.02.2022"));
prints "{MonthOfYear=2, DayOfMonth=31, YearOfEra=2022},ISO"
System.out.println(DateTimeFormatter.ofPattern("dd.MM.uuuu").withResolverStyle(ResolverStyle.STRICT).parse("31.02.2022"));
throws java.time.DateTimeException: Invalid date 'FEBRUARY 31'
So you must use 'dd.MM.uuuu' to get the expected behaviour.
Can anyone tell me why if I type in MATLAB
datestr('17-03-2016','dd-mmmm-yyyy')
I get
06-September-0022
From the datestr docs
DateString = datestr(___,formatOut) specifies the format of the output text using formatOut. You can use formatOut with any of the input arguments in the above syntaxes.
So in your example the 'dd-mmmm-yyyy' is specifying the output format, not the input format.
Also
DateString = datestr(DateStringIn) converts DateStringIn to text in the format, day-month-year hour:minute:second. All dates and times represented in DateStringIn must have the same format.
where
'dd-mm-yyyy' is not in the list of allowed DateStringIn formats AND the documentation explicitly recommends using datenum to ensure correct behaviour. (Note: I underlined the wrong must in the sentence, it's the second must I wanted to emphasise)
So Sandar_Usama's answer of
datestr(datenum('17-03-2016','dd-mmmm-yyyy'))
is the officially correct method straight out of the docs.
Bottom line, always read the documentation.
Use this instead: datestr(datenum('17-03-2016','dd-mmmm-yyyy'))
To address the last unanswered point in this question, why does datenum behave like this?
>> datestr(datenum('17-03-2016'))
ans =
06-Sep-0022
Without explicitly telling datestr and datenum how it should treat the input, it will try to match against the expected formats. Since none of the documented formats match (see #dan's answer), it fails.
Although what it does next is undocumented, at least up to whatever version of Matlab we are running, it falls into a "last resource" attempt to give you a date number.
Matlab will try to parse different month names from your input, remove non-numeric characters, and then timedate elements from the string. In your case, they are 17, 03, and 2016. The first is expected to be either month or year. Since there's no 17th month, it is treated as year. Then 03 is the month, and 2016 is the day.
Now, March 2016th, 17 is not a valid date, but Matlab will give it a slack and read as 1985 days past March 31st, 17. And that gives us September 6th, 22.
Because Matlab's timestamp is a floating number for the number of days since its epoch, you can trigger that answer, using valid dates, like so:
>> datestr(datenum('0017-03-31') + 1985)
ans =
06-Sep-0022
I have a few places where I need to change how the date format displays in my Alfresco share:
Calendar Format
Needs to be in MM/DD/YYYY format.
Date in Info.ftl Control
Needs to be in DDD MM DD YYYY format.
Date().toString()
This is being displayed in a data list. Ideally it should read: "Tue Jul 2015 8:27:51 (EST)"
I located common.properties and made the following changes:
## Date Formats
#Used client side (uses Alfresco.util.formatDate)
date-format.default=mmm ddd d yyyy HH:MM:ss
date-format.defaultDateOnly=mmm ddd d yyyy
date-format.shortDate=m/d/yy
date-format.mediumDate=mmm d, yyyy
date-format.mediumDateNoYear=mmm d
date-format.longDate=mmmm dd, yyyy
date-format.longDateNoYear=mmmm dd
date-format.fullDate=mmmm, d dddd, yyyy
date-format.fullDateTime=mmmm, d dddd, yyyy 'at' h:MM TT
date-format.shortTime=h:MM TT
date-format.mediumTime=h:MM:ss TT
date-format.longTime=h:MM:ss TT Z
date-format.monthYear=mmmm yyyy
date-format.dayDateMonth=mmmm, d dddd
date-format.am=am
date-format.pm=pm
But none of them seem to affect any date formats anywhere. My questions:
Where do I need to make additional changes to get the above formats to work?
How do I change the time zone?
Essentially, I need to change everything to Eastern US time zone and formats.
Different files where date format are mentioned. Each of them are responsible for rendering dates in different places
<ALF_HOME>\tomcat\webapps\share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\components\form\form.get_en.properties
<ALF_HOME>\tomcat\webapps\share\WEB-INF\classes\alfresco\messages\common.properties
<ALF_HOME>\tomcat\webapps\share\WEB-INF\classes\alfresco\messages
common.properties\slingshot.properties
We need to edit the \tomcat\webapps\share\WEB-INF\classes\alfresco\messages\common.properties as well as \tomcat\webapps\share\WEB-INF\classes\alfresco\messages\common_en.properties the second file the locale specific file should also be modified.
Modify the below key's value
date-format.default=mm/dd/yyyy
These changes only impact the display format of date, if we need to make changes for form we need to modify in \tomcat\shared\classes\alfresco\web-extension\site-webscripts\org\alfresco\components\form**form.get_en.properties** and form.get.properties.
Hope this will help you :)
When formatting dates, the use of %m=month, %y=day, and %d=day are obvious and memorable, but what does the b in %b stand for?
In other words, why does %b indicate abbreviated month? Is this simply working through alphabet to describe the various terms or is there a meaningful link?
I found plenty of sites that describe the format (e.g. W3Schools, but I haven't been able to find the etymology of the %b term.
You are looking for a semantic rationale or mnemonic when there is none. Lower case b was probably chosen for symmetry with A, a for weekday and abbreviated weekday.
B and b provide the same for month names.
In date formatting, %m is used for minutes; therefore, it cannot be used for month.
I don't think that the 'b' in %b stands for anything in particular. It was likely the first available single character value in the alphabet to represent the month.