How to convert TypeScript Date to a Java Date

孤街醉人 提交于 2021-01-24 09:33:52

问题


I have a Spring application and i receive a date from an angular client as a String, how can i convert this date to a Java Date, following is the TypeScript Date format :

TypeScript Date Format : Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

Java Date Format : Mon Jan 04 00:00:00 CET 2021


回答1:


java.time

how can i convert this date to a Java Date, following is the TypeScript Date format :

TypeScript Date Format : Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

java.time provides you with DateTimeFormatterBuilder using which you can define a complex format for parsing/formatting as shown below:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.HashSet;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)";
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                    .parseCaseInsensitive()
                                    .appendPattern("EEE MMM dd uuuu HH:mm:ss")
                                    .appendLiteral(" ")
                                    .appendZoneRegionId()
                                    .appendOffset("+HHmm", "Z")
                                    .appendLiteral(" (")
                                    .appendZoneText(TextStyle.FULL)
                                    .appendLiteral(")")
                                    .toFormatter(Locale.ENGLISH);
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

Output:

2021-01-04T00:00+01:00[Europe/Paris]

Java Date Format : Mon Jan 04 00:00:00 CET 2021

A date-time object is supposed to store the information about the date, time, timezone etc., not about the formatting. You can format a date-time object into a String object with the pattern of your choice using date-time formatting API.

  • The date-time formatting API for the modern date-time types is in the package, java.time.format e.g. java.time.format.DateTimeFormatter, java.time.format.DateTimeFormatterBuilder etc.
  • The date-time formatting API for the legacy date-time types is in the package, java.text e.g. java.text.SimpleDateFormat, java.text.DateFormat etc.

Given below is how you can format zdt (obtained above) into a custom format:

DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
String strDateTimeFormatted = zdt.format(dtfOutput);
System.out.println(strDateTimeFormatted);

Output:

Mon Jan 04 00:00:00 CET 2021

Learn about the modern date-time API from Trail: Date Time.

In case you want to convert zdt (obtained above) into java.util.Date, you can do so as shown below:

Date date = Date.from(zdt.toInstant());
System.out.println(date);

A note about the legacy date-time API:

The java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the milliseconds from the Epoch of January 1, 1970. When you print an object of java.util.Date, its toString method returns the date-time calculated from this milliseconds value. Since java.util.Date does not have timezone information, it applies the timezone of your JVM and displays the same. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFomrat and obtain the formatted string from it. 3. The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.

  • For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
  • If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.



回答2:


Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

This is an ambiguous timestamp. Political entities and the world at large is free to redefine what CEST means, at which point GMT+0100 means one thing, and CST means another. Furthermore, CEST has implications for any 'math' done on this date that are different from GMT+0100.

For example, if I want to know the date 6 months from that one, then if CST is leading, you'd want:

Thu Jul 04 2021 00:00:00 GMT+0200 (Central European Daylight Time)

or possibly you'd want that time but one hour earlier - another open question, there is no clear answer to that question inherent in the idea 'add 6 months to this timestamp', so you will have to specify it, because otherwise you get some random guess by the system, and you almost never want your computer / programming language to guess at a 50/50 concept like this.

If GMT+0100 is leading, you end up with:

Thu Jul 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

Which is completely bizarre there are zero places on the entire planet where this timestamp makes sense as printed: Nobody is on CEST on the 4th of july, anywhere. It's a timestamp that is 'real', and yet used by literally 0 people.

Thus, before continuing, first you need to ask yourself which bits and bobs from what you do have, you want to preserve when you convert it. Note that there are 3 different ideas of time:

  • 'solarflares' time: Commonly measured as millis-since-epoch. This is devoid of human concepts such as timezones. To record the exact instant in time that an event happened, or will happen, if the event is not a human appointment (i.e. when a solarflare is predicted to happen or did happen, hence the name 'solarflares' time). In java, best represented by java.time.Instant.

  • 'appointment' time: Commonly measured as a big sack of numbers: A year, a month, a day, hour, minute, second, and a timezone. And not one of those GMT+0100 useless zones, but something like Europe/Amsterdam. Something like Central European Standard Time is somewhat common, but also a very bad idea. These names have no clear meaning, something like Europe/Amsterdam is designed to most likely always have clear meaning, that's a proper zone. The idea is: Let's say you make an appointment with your dentist, in Amsterdam, for next month. It sure seems like a solarflares kind of deal, but it is not: if the netherlands decides to join a different timezone, the absolute # of seconds until your appointment changes along. Whereas that solarflare is not going to occur an hour earlier just because some political entity decreed it so.

  • 'alarm' time: Like appointment time but no zone info as a fundamental. If you set your alarm to wake you up at 8 in the morning and you hop in a plane and fly west a bunch, you want the alarm to still go off at 8 in the morning local time: The # of seconds until the alarm goes off should change as you move across zones.

So, what is your time value intended to represent?

If 'solarflares' time.

Then the job is to first convert this into a java.time.Instant object, and take it from there. For example, convert back to appointment time via .atZone(), and then print it to a string that looks like that using a java.time.format.DateTimeFormatter. Imagine the input was in singapore time instead, then with this strategy the output is still in CET. Also, I get the feeling you showed the string not because you need the string to be formatted like that, but because you erroneously think that java stores time in this string format. It doesn't; java stores appointment time as an object with a field for year, month, day, etc. The printing of this to a string is separated out, and controlled by a formatter. You can make a formatter to print it any way you please.

Parsing this to a j.t.Instant value can be done based on the GMT+0100, you can ignore the CEST trailing text.

If 'appointments' time.

Then you need to parse this out which is non-trivial; the GMT+0100 is not what you wanted, that IS a legal zone, but not a useful one (no country in the CEST zone uses GMT+0100. There are places on the planet that are GMT+0100 year round. They are not, however, anywhere near central europe). Thus, the relevant bits are everthing except GMT+0100, including CEST, and that is not a standard date format, and 'Central European Standard Time' is not a thing java.time can recognize as far as I know. You'll need a table of all the possible strings that typescript can generate at that point.

If 'alarm time'

Then you can just stop parsing after the final :00 and toss the rest. Use a regexp to strip it out, then parse into a LocalDateTime using the LocalDateTime.of(stringValue, formatter) method. Easy enough.

A note of advice

Try to course your TypeScript to print this stuff in something other than that. One great way to do it is to combine solarflares time with an explicit zone (like Europe/Amsterdam, not like Central European Standard Time). This is much more easily reparsed into any of the 3 different conceptual ways to refer to time.




回答3:


You can use epoch time to share time between client and server, it´s an easy way.

Typescript epoch time management

const epoch = new Date().getTime();
console.log(epoch);

const date = new Date(epoch);
console.log(date);

Result:

1609801111672

Date Mon Jan 04 2021 22:58:31 GMT+0000 (Western European Standard Time)

Java epoch time management with java.util.Date

long epoch = new Date().getTime();  
log.debug( "Epoch: {}", epoch );
        
Date date = new Date(epoch);    
log.debug( "Date: {}", date );

Result

Epoch: 1609801111672

Date: 2021-01-04T22:58:31.672Z


来源:https://stackoverflow.com/questions/65564052/how-to-convert-typescript-date-to-a-java-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!