How can I parse a time string, such as Sun May 27 13:02:04 +0200 2012, to a tuple in UTC, using python3? The closest I can get is time.strptime(str, '%a %b %d %H:%M:%S %z %Y'), but it seems the offset is parsed but ignored. The above example is parsed to:
time.struct_time(tm_year=2012, tm_mon=5, tm_mday=27, tm_hour=13, tm_min=1, tm_sec=35, tm_wday=6, tm_yday=148, tm_isdst=-1)
but I expected tm_hour=11.
Related: Convert string timestamp (with timezone offset) to local time. . ? python, Parsing time string in Python. Answers to both suggests the use of dateutil, but I'd prefer using the standard library, if possible.
tm_hour=11 would be incorrect. The time in the timestamp is 13:02:04, no matter what the offset is.
What you want to do is to convert that timestamp into a time in GMT, which the standard library won't do for you. So you will just have to extract the offset yourself (which is trivial) and then subtract it from the time.
I'd also recommend you to use the datetime library for this, date/time manipulation is much easier there, you can easily create a timedelta object from the offset and subtract that from the datetime object.
Related
I am using Golang and time.Time to Parse a given string into a time object.
Using RFC3339 and time.Parse here is an example of my code:
t, err := time.Parse(time.RFC3339, "2020-08-08T00:22:44Z07:00")
if err != nil {
return nil, err
}
I get the follow errors.
When I include timezone offset I am getting:
ERRO[0002] parsing time "2020-08-08T00:22:44Z07:00": extra text: 07:00
When I don't include the timezone offset I am getting:
ERRO[0002] parsing time "2020-08-08T00:15:36" as "2006-01-02T15:04:05Z07:00": cannot parse "" as "Z07:00"
How do I avoid this issue when parsing time into a structured object?
The presence of the character Z in the Go time.RFC3339 constant "2006-01-02T15:04:05Z07:00" does not mean that a date conforming to the pattern is supposed to include a Z followed by the time zone offset.
In fact, a date with Z followed by anything else is not a valid RFC3339 date. Hence, your first error extra text: 07:00
The Z stands for "Zulu Time", i.e. UTC time zone. From the RFC3339 specs:
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".
So the Z alone is already providing the time zone information, that is, UTC.
As #Flimzy noted in the comments, 2020-08-08T00:22:44Z would be a valid RFC3339 date.
t, err := time.Parse(time.RFC3339, "2020-08-08T00:22:44Z")
if err != nil {
panic(err)
}
fmt.Println(t) // 2020-08-08 00:22:44 +0000 UTC
Now, if you read the RFC3339 standard further, you see this definition:
time-zone = "Z" / time-numoffset
time-numoffset = ("+" / "-") time-hour [[":"] time-minute]
Which means that the time zone part of the date is either a Z or the offset. Clearly, since the Z already represents the offset 00:00, you can't have one more +/-HH:mm offset in the same date string.
But this also means that Z or the +/-HH:mm must be present. So if you remove both of them, you get your second error: cannot parse "" as "Z07:00"
The parser is attempting to read the "2020-08-08T00:15:36" string as RFC3339 so it expects either a Z or an offset after the seconds (or milliseconds, if any).
In conclusion, the Z07:00 in the Go time.RFC3339 pattern is just a representation of the fact that the date string is supposed to include a time zone. A valid RFC3339 date string must include either Z or the offset.
I need a date time string formatted as %Y-%m-%d %H:%M:%S.
I can't figure out how to use Lua's standard functions os.date() and os.time() to achieve that.
os.date is the function you are looking for. Its first optional parameter, format, does what you want:
os.date('%Y-%m-%d %H:%M:%S')
--> 2019-04-02 10:50:52
From the Lua 5.3 manual on os.date:
os.date ([format [, time]])
Returns a string or a table containing date and time, formatted according to the given string format.
If format starts with '!', then the date is formatted in Coordinated Universal Time.
If format is not "*t", then date returns the date as a string, formatted according to the same rules as the ISO C function strftime.
You can learn more about the formatting rules of C's strftime here.
In case you don't get your local time for whatever reason you can simply add the required offset.
local timeShift = 3 * 60 * 60 -- +3 hours
os.date('%Y-%m-%d %H:%M:%S', os.time() + timeShift)
--> 2019-04-02 18:24:15 for 15:24:15 UTC
I use lib https://github.com/Tieske/date. Get localtime -
date(true):addminutes("your offset"):fmt('%Y-%m-%d %H:%M:%S'),
This is a follow-up question to the one I asked just a little while ago.
I couldn't find a single example (sorry for my Google skills) on the Haskell site which shows how to use the Data.Time functions to convert a formatted String to UTCTime and then be able to add/subtract minutes/seconds from that and convert back the UTCTime to formatted String.
I am looking for an example that shows how to convert a String (e.g. like "10:20:30" to UTCTime and then add 1000 seconds to that time. How to do this Haskell using the Data.Time library without using IO at all?
The type of the function should be FormatTime -> String -> UTCTime.
The function should use TimeLocale or FormatTime as locale/formatting is needed.
There are so many functions in the library and so many types that it just baffling. readTime, TimeLocale, ParseTime t, NominalDiffTime, Time and what not.
Please do not just point to docs on the Haskell site. Most of the docs there are just a dump of type signatures from the source code, without almost any examples. Sorry if this is coming as rant, but I have spent a lot of time trying to figure out something from those docs.
Compare this to Python docs on time. So many beautiful examples.
Thank god, there is SO.
import Data.Time
timeFormat = "%H:%M:%S"
understandTime = parseTimeOrError True defaultTimeLocale timeFormat
time :: UTCTime
time = understandTime "10:30:20"
λ> time
1970-01-01 10:30:20 UTC
Let's break down what's going on:
timeFormat is simply a string, describing how we expect the time to be passed to us.
we partially apply parseTimeOrError, using defaultTimeLocale for the locale, and previously defined timeFormat for the expected format.
We now have a understandTime function, that can take in a time as a String. When using it, we need to explicitly set the expected output type to UTCTime (this is what time :: UTCTime does). If we were to use understandTime within the context of a function that already expects a UTCTime, this would be unnecessary (for example addUTCTime 1000 (understandTime "10:30:20"))
We get back time. Note that the year, day, month and timezone default to 1970-01-01 and UTC because we do not explicitly read them in timeFormat.
In the Hadoop infrastructure (Java-based) I am getting timestamps as string values in this format:
2015-10-01T04:22:38:208Z
2015-10-01T04:23:35:471Z
2015-10-01T04:24:33:422Z
I tried different patters following examples for SimpleDateFormat Java class without any success.
Replaced 'T' with ' ' and 'Z' with '', then
"yyyy-MM-dd HH:mm:ss:ZZZ"
"yyyy-MM-dd HH:mm:ss:zzz"
"yyyy-MM-dd HH:mm:ss:Z"
"yyyy-MM-dd HH:mm:ss:z"
Without replacement,
"yyyy-MM-dd'T'HH:mm:ss:zzz'Z'"
In fact, this format is not listed among examples. What should I do with it?
Maybe those 3 digits are milliseconds, and time is in UTC, like this: "yyyy-MM-dd'T'HH:mm:ss.SSSZ"? But it still should look like "2015-11-27T10:50:44.000-08:00" as standardized format ISO-8601.
Maybe, this format is not parsed correctly in the first place?
I use Ruby, Python, Pig, Hive to work with it (but not Java directly), so any example helps. Thanks!
I very strongly suspect the final three digits are nothing to do with time zones, but are instead milliseconds, and yes, the Z means UTC. It's a little odd that they're using : instead of . as the separator between seconds and milliseconds, but that can happen sometimes.
In that case you want
"yyyy-MM-dd'T'HH:mm:ss:SSSX"
... or use
"yyyy-MM-dd'T'HH:mm:ss:SSS'Z'"
and set your SimpleDateFormat's time zone to UTC explicitly.
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.