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 use hh 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

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -