Im trying to convert a bunch of NSStrings into NSDate objects. Here is an example string:
2013-04-25T15:51:30.427+1.00
But I can't figure out what format it is in, so far I have (The question marks are the bits I'm stumped with):
yyyy-MM-ddTHH:mm:ss????zzz
The main problem I'm having is with the '.427' part although if I'm making a mistake elsewhere, let me know :)
Does anyone have any ideas? Or could point me to a list of all the possible date format specifiers? I found this: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx which is useful but it doesn't appear to have any specifier for the '.427' part that I'm stuck on.
Any help is appreciated, Thanks.
The proper format is yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ.
See Unicode Date Format Patterns.
Also, the ZZZZZ format for the +00:00 timezone format was added to iOS 6 and is not supported under iOS 5 or earlier.
It is a valid date format as specified by ISO 8601, according to W3
The formats are as follows. Exactly the components shown here must be
present, with exactly this punctuation. Note that the "T" appears
literally in the string, to indicate the beginning of the time
element, as specified in ISO 8601.
Year:
YYYY (eg 1997) Year and month:
YYYY-MM (eg 1997-07) Complete date:
YYYY-MM-DD (eg 1997-07-16) Complete date plus hours and minutes:
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00) Complete date plus hours, minutes and seconds:
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00) Complete date plus hours, minutes, seconds and a decimal fraction of a
second
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
where:
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
In your case, the date has millisecond accuracy, try adding .sss to the format
Related
I need to convert this server date (Given from kinvey request) into local timezone.
I'm using the following code:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-ddTHH:mm:ss.sTZD"
print(dateFormatter.dateFromString(newValue))
The date format is this:
ect = "2016-08-28T16:30:06.553Z" or
lmt = "2016-08-28T16:30:06.553Z"
When I print the date it is nil, do you know what I'm doing wrong ?. I think it could be the end of the dateFormat
If your app can target only iOS7+, you can use format symbols described in:
Fixed Formats (in Data Formatting Guide)
Unicode Technical Standard #35 version tr35-31
second | S | 1..n | 3456 | Fractional Second - truncates (like other
time fields) to the count of letters. (example shows display using
pattern SSSS for seconds value 12.34567)
zone | X | 1 | -08,+0530,Z | The
ISO8601 basic format with hours field and optional minutes field. The
ISO8601 UTC indicator "Z" is used when local time offset is 0. (The
same as x, plus "Z".)
So, to parse fractional second, use uppercase 'S',
and 'X' for timezone including "Z" as UTC.
Try this:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSX"
(I escaped 'T' as it may be used as another time formatting symbol in the future.)
PS. Though I couldn't have found a thread describing the date format which interprets "Z" as UTC+0000, ignoring or removing it may not be a bad solution, if some conditions met. Please find your best solution.
Consider this example:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Parse(time.RFC3339, time.RFC3339))
}
The output is:
0001-01-01 00:00:00 +0000 UTC parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00
Why can't time.Parse() handle a layout as a value? What's missing here?
UPDATE: Cutting off the time zone value (but not the 'Z' delimiting the time from the zone) fixes it:
fmt.Println(time.Parse(time.RFC3339, "2015-09-15T11:50:00Z"))
Why can't time.Parse() handle time zone info when using time.RFC3339 as the layout string?
http://play.golang.org/p/p3fHfJNHVK
UPDATE: JimB's answer led me to read from RFC3339 and I found these examples that clarify further:
Here are some examples of Internet date/time format.
1985-04-12T23:20:50.52Z
This represents 20 minutes and 50.52 seconds after the 23rd hour of
April 12th, 1985 in UTC.
1996-12-19T16:39:57-08:00
This represents 39 minutes and 57 seconds after the 16th hour of
December 19th, 1996 with an offset of -08:00 from UTC (Pacific
Standard Time). Note that this is equivalent to 1996-12-20T00:39:57Z
in UTC.
The time.RFC3339 format is a case where the format string itself isn't a valid time. You can't have a Z and an offset in the time string, but the format string has both because the spec can contain either type of timezone specification.
Both of these are valid RFC3339 times:
"2015-09-15T14:00:12-00:00"
"2015-09-15T14:00:13Z"
And the time package needs to be able to parse them both using the same RFC3339 format string.
As noted, 2006-01-02T15:04:05Z07:00 is an invalid IETF RFC-3339 time format. Here's an explanation.
The reason you cannot have both Z and an offset is that they are both ways to represent a time offset. Z is equivalent to +00:00 indicating a zero hour/minute offset, or no offset. You cannot say both +00:00 offset and +07:00 offset in the same time representation.
The following is the Z definition in the RFC-3339 Section 2:
https://www.rfc-editor.org/rfc/rfc3339#section-2
Z A suffix which, when applied to a time, denotes a UTC
offset of 00:00; often spoken "Zulu" from the ICAO
phonetic alphabet representation of the letter "Z".
Of note, while Z is equivalent to +00:00, they are both different from -00:00 which indicates known UTC time with an unknown offset, as described in RFC-3339 Section 4.3:
https://www.rfc-editor.org/rfc/rfc3339#section-4.3
4.3. Unknown Local Offset Convention
If the time in UTC is known, but the offset to local time is unknown,
this can be represented with an offset of "-00:00". This differs
semantically from an offset of "Z" or "+00:00", which imply that UTC
is the preferred reference point for the specified time. RFC2822
[IMAIL-UPDATE] describes a similar convention for email.
I am working on REST calls where I need to send date in "2006-09-01T07:00:00.000+0000" format.
User enters date in "YYYY/MM/DD" format and I am using "moment.js" to format the date in ISO 8601 using this format "YYYY-MM-DDTHH:MM:SS.MMMZ" . But it gives me this output "1969-06-20T00:06:00.Jun-07:00".
So, how do I get date in this format "2006-09-01T07:00:00.000+0000" using moment.js OR Javascript ?
Yes, it is ISO 8601. 2006-09-01T07:00:00.000+0000 is the first day of the ninth month of the year 2006, 7 hours, 0 minutes, 0.000 seconds offset 0 hours from UTC. Whether or not decimals are allowed is up to the parties exchanging dates (which is a fancy way of ISO saying "it's optional").
4.2.2.4 Representations with decimal fraction
If necessary for a particular application a decimal fraction of hour, minute or second may be included. If a decimal fraction is included, lower order time elements (if any) shall be omitted and the decimal fraction shall be divided from the integer part by the decimal sign specified in ISO 31-0, i.e. the comma [,] or full stop [.]. Of these, the comma is the preferred sign. If the magnitude of the number is less than unity, the decimal sign shall be preceded by two zeros in accordance with 3.6.
The interchange parties, dependent upon the application, shall agree the number of digits in the decimal fraction. The format shall be [hhmmss,ss], [hhmm,mm] or [hh,hh] as appropriate (hour minute second, hour minute, and hour, respectively), with as many digits as necessary following the decimal sign. A decimal fraction shall have at least one digit. In the examples below it has been agreed to give the smallest time element a decimal fraction with one digit.
(As pointed out by #chansen, technically it should be 2006-09-01T07:00:00.000+00:00 with a separator on the time zone because according to 4.3.3(d) every part must use either the basic format (no separators) or the extended format (with separators), but nobody bothers with that, strptime can't produce that format, and you'll probably break some ISO 8601 parsers).
Outputting this is covered in other answers for both Javascript and moment.js.
Javascript has Date.toISOString for output. Date.new will also accept an ISO 8601 string. Every recent browser should support it, though Internet Explorer only added it in version 9 (IE 8 still represents 5% of desktop users).
Here's the moment.js docs on String formatting. YYYY-MM-DDTHH:MM:SS.MMMZ is incorrect because you're using M to mean three different things. What you want is YYYY-MM-DDTHH:mm:ss.SSSZZ.
YYYY - year
MM - month number (2 digit)
DD - day of month (2 digit)
HH - hours (2 digit, 24 hour format)
mm - minutes (2 digit)
ss - seconds (2 digit)
SSS - thousands of seconds
ZZ - UTC offset
The format that worked for me for 2006-09-01T07:00:00.000+0000
was: yyyy-MM-dd'T'hh:mm:ss.sssZ
I am trying to convert date from rails api to NSDate object.
The response date from api is 2014-11-05T16:29:09.614Z
What does .614Z mean?
The int before the Z are the milliseconds, the Z stand for Zulu which is the time zone:
From http://en.wikipedia.org/wiki/Coordinated_Universal_Time:
The UTC time zone is sometimes denoted by the letter Z—a reference to
the equivalent nautical time zone (GMT), which has been denoted by a Z
since about 1950. The letter also refers to the "zone description" of
zero hours, which has been used since 1920 (see time zone history).
Since the NATO phonetic alphabet and amateur radio word for Z is
"Zulu", UTC is sometimes known as Zulu time.
Thus you time format is:
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
If you include the Z like in the example above the date will correctly converted to the devices current timezone.
I would like to return the local time as string but with leading zeros. I tried this:
{{Year, Month, Day}, {Hour, Minute, Second}} = erlang:localtime().
DateAsString = io_lib:format("~2.10.0B~2.10.0B~4.10.0B~2.10.0B~2.10.0B~2.10.0B",
[Month, Day, Year, Hour, Minute, Second]).
But if some of the components is one digit, the returned string is:
[["0",57],"29","2011","17","33","34"]
The current month 9 is printed as ["0",57].
Please, help.
Thank you.
Try:
1> lists:flatten([["0",57],"29","2011","17","33","34"]).
"09292011173334"
io_lib:format/2 (and it's companion io:format/2) actually returns a deep IO list. Such a list is printable and can be sent on a socket or written to a file just as a flat string, but is more efficient to produce. Flattening is often useless, because in all cases where the string will be printed or output to a file/socket it will automatically be flattened by Erlang.
You want to be using something like this:
DateAsString = io_lib:format("~2..0w~2..0w~4..0w~2..0w~2..0w~2..0w",
[Month, Day, Year, Hour, Minute, Second]).
The more common w format modifier does the right thing here, what with base and such, so there's no need to use the more complex B modifier. 2..0 says "2 characters wide, zero padded, no precision specified." We don't need precision here, since we're dealing with integers.