java - How to convert timestamp string to epoch time? -
i have time stamp in format 2017-18-08 11:45:30.345
.
want convert epoch time, doing below:
string timedatestr = "2017-18-08 11:45:30.345"; datetimeformatter dtf = datetimeformatter.ofpattern("yyyy-dd-mm hh:mm:ss.sss"); zoneddatetime zdt = zoneddatetime.parse(timedatestr, dtf); system.out.println(zdt.toinstant().toepochmilli());
i getting below error:
java.time.format.datetimeparseexception: text '2017-18-08 11:45:30.345' not parsed: unable obtain zoneddatetime temporalaccessor
i tried different formats still getting errors.
note: originally question had input 2017-18-08 12:60:30.345
(with 60
in minutes field), it edited (the time changed 12:60
11:45
), decided keep answer discussing original input (12:60
), works edited version (11:45
).
zoneddatetime
needs timezone or offset, input string
doesn't have (it has date , time).
there details in input:
- the minute value
60
, not accepted: valid values 0 59 (actually there's way accept this, see "lenient parsing" below) - the
hh
clock-hour-of-am-pm field, needs am/pm designator resolved. don't have it, should usehh
pattern instead
so pattern must yyyy-dd-mm hh:mm:ss.sss
, input can't have 60
minutes value (unless use lenient parsing, i'll explain below) , can't direclty parse zoneddatetime
because doesn't have timezone/offset designator.
one alternative parse localdatetime
, define in timezone/offset date is. in example below, i'm assuming it's in utc:
// change 60 minutes 59 (otherwise doesn't work) string timedatestr = "2017-18-08 12:59:30.345"; datetimeformatter dtf = datetimeformatter.ofpattern("yyyy-dd-mm hh:mm:ss.sss"); // parse localdatetime localdatetime dt = localdatetime.parse(timedatestr, dtf); // assume localdatetime in utc instant instant = dt.toinstant(zoneoffset.utc); system.out.println(instant.toepochmilli());
this output:
1503061170345
which equivalent of 2017-18-08 12:59:30.345
in utc.
if want date in timezone, can use zoneid
class:
// localdatetime in timezone zoneddatetime z = dt.atzone(zoneid.of("europe/london")); system.out.println(z.toinstant().toepochmilli());
the output is:
1503057570345
note result different, because same local date/time represents different instant
in each timezone (in each part of world, local date/time 2017-18-08 12:59:30.345
happened in different instant).
also note api uses iana timezones names (always in format region/city
, america/sao_paulo
or europe/berlin
). avoid using 3-letter abbreviations (like cst
or pst
) because ambiguous , not standard.
you can list of available timezones (and choose 1 fits best system) calling zoneid.getavailablezoneids()
.
you can use system's default timezone zoneid.systemdefault()
, can changed without notice, @ runtime, it's better explicity use specific one.
there's option convert localdatetime
offset (like -05:00
or +03:00
):
// localdatetime in +03:00 offset system.out.println(dt.toinstant(zoneoffset.ofhours(3)).toepochmilli());
the output equivalent local date/time in offset +03:00
(3 hours ahead of utc):
1503050370345
lenient parsing
as @menohochschild reminded me in comments, can use lenient parsing accept 60
in minutes field (using java.time.format.resolverstyle
class):
string timedatestr = "2017-18-08 12:60:30.345"; datetimeformatter dtf = datetimeformatter.ofpattern("yyyy-dd-mm hh:mm:ss.sss") // use lenient parsing .withresolverstyle(resolverstyle.lenient); // parse localdatetime localdatetime dt = localdatetime.parse(timedatestr, dtf);
in case, 60 minutes adjusted next hour, , localdatetime
be:
2017-08-18t13:00:30.345
daylight saving time
if decide use utc or fixed offset (using zoneoffset
class), can ignore section.
but if decide use timezone (with zoneid
class), must take care of dst (daylight saving time) issues. i'm gonna use timezone live in example (america/sao_paulo
).
in são paulo, dst starts @ october 15th 2017: @ midnight, clocks shift 1 hour forward midnight 1 am. local times between 00:00 , 00:59 don't exist in timezone. if create local date in interval, it's adjusted next valid moment:
zoneid zone = zoneid.of("america/sao_paulo"); // october 15th 2017 @ midnight, dst starts in sao paulo localdatetime d = localdatetime.of(2017, 10, 15, 0, 0, 0, 0); zoneddatetime z = d.atzone(zone); system.out.println(z);// adjusted 2017-10-15t01:00-02:00[america/sao_paulo]
when dst ends: in february 18th 2018 @ midnight, clocks shift back 1 hour, midnight 23 pm of 17th. local times 23:00 23:59 exist twice (in dst , in non-dst), , must decide 1 want:
// february 18th 2018 @ midnight, dst ends in sao paulo // local times 23:00 23:59 @ 17th exist twice localdatetime d = localdatetime.of(2018, 2, 17, 23, 0, 0, 0); // default, gets offset before dst ends zoneddatetime beforedst = d.atzone(zone); system.out.println(beforedst); // before dst end: 2018-02-17t23:00-02:00[america/sao_paulo] // offset after dst ends zoneddatetime afterdst = beforedst.withlateroffsetatoverlap(); system.out.println(afterdst); // after dst end: 2018-02-17t23:00-03:00[america/sao_paulo]
note dates before , after dst ends have different offsets (-02:00
, -03:00
). affects value of epochmilli.
you must check when dst starts , ends in timezone choose , check adjustments accordingly.
Comments
Post a Comment