简体   繁体   中英

How convert Timestamp to Date

Other system send for us Timestamp in their time zone.If we run that in cloud in other system is +2 hours. Local is good because the server is the same time zone. How can I be sure that the time will always be right?

String TIME_STAMP_FORMAT = "yyyy-MM-dd-HH.mm.ss.SSSSSS";

DateTimeFormatter TIME_STAMP_FORMATTER = DateTimeFormatter.ofPattern(TIME_STAMP_FORMAT, Locale.getDefault());

private static Timestamp parseTimestamp(String dateString) {
        try {
            return Timestamp.valueOf(LocalDateTime.parse(dateString, TIME_STAMP_FORMATTER));
        } catch (DateTimeParseException e) {
            log.error("Not able to parse timestamp", e);
        }
        return null;
    }

Date afterParse =  parseTimestamp('2018-12-31-12.30.50.000200')

tl;dr

How can I be sure that the time will always be right?

  • Include an indicator of time zone or offset-from-UTC with your date-time input string.
  • Use standard ISO 8601 formats when exchanging date-time values.
  • Use only java.time classes in Java. Never use Date , Timestamp , Calendar , etc.
  • Tip: Adjust values from other zones to UTC before sending (generally speaking).

If not possible, then here is a workaround. This assumes you know the time zone intended by the sender of this poor data.

LocalDateTime                           // Represent a date and time-of-day without the context of a time zone or offset-from-UTC. NOT a moment, NOT a point on the timeline. A meaningless value until you assign a zone/offset.
.parse(
    "2018-12-31-12.30.50.000200" ,      // Avoid such custom formats. Use only ISO 8601 when exchanging date-time values textually.
    DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" )  // Define formatting pattern to match youre input.
)                                       // Returns a `LocalDateTime` object.
.atZone(                                // Give meaning to the `LocalDateTime` object by applying a time zone.
    ZoneId.of( "Africa/Tunis" )         // Always specify a time zone with `Continent/Region` name, never the 2-4 character pseudo-zones popularly seen in the media.
)                                       // Returns a `ZonedDateTime` object.
.toInstant()                            // Adjust from a time zone to UTC by extracting an `Instant` object. Same moment, same point on the timeline, different wall-clock time.

See this code run live at IdeOne.com .

Best to avoid java.util.Date class. But if you must interoperate with old code not yet updated to java.time , you can convert. Call on the new methods added to the old classes such as Date.from( Instant ) .

Avoid legacy classes

Never use java.sql.Timestamp nor java.util.Date . All of the date-time classes bundled with the earliest versions of Java are now legacy, per the adoption of JSR 310. Use only the modern java.time classes.

Wrong data type

You are using the wrong data type. To track a moment, a specific point on the timeline, you must have a time zone or offset-from-UTC. The LocalDateTime class exactly the wrong class to use here. That class purposely lacks any concept of zone or offset. So it is the opposite of what you want.

To track a moment, use Instant , OffsetDateTime , or ZonedDateTime .

Java中的日期时间类型表,包括现代的和传统的。

Where the java.time classes have methods with an optional time zone ( ZoneId ) or offset-from-UTC ( ZoneOffset ) argument, consider the argument required. Always pass a zone/offset. Then you never need worry about how the sysadmin is setting the JVM's current default time zone at runtime.

ZonedDateTime.now(                    // Capture the current moment as seen through the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "Pacific/Auckland" )
)

Or, use Instant which is always in UTC, by definition.

Instant.now()                         // Capture the current moment in UTC.

Specify a proper time zone name in the format of Continent/Region , such as America/Montreal , Africa/Casablanca , or Pacific/Auckland . Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ISO 8601

Your question is not clear, but it seems you are receiving an input string for a date-time in a custom format. I suggest you educate the people publishing that data about the ISO 8601 standard. This standard defines practical formats for date-time values being exchanged between systems textually.

The java.time classes use the ISO 8601 formats by default when parsing/generating strings.

Workaround

If the data publisher is sending you values such as 2018-12-31-12.30.50.000200 in order to communicate a moment, they have failed. A date and time-of-day without a zone or offset is useless, like communicating an amount of money without indicating a currency.

Do you know for certain the time zone that was implicitly assumed by the sender of this faulty data input? If so, apply it, as a clumsy stop-gap measure for their poor practice.

First parse your input as a LocalDateTime given that it lacks any indicator of zone/offset.

String input = "2018-12-31-12.30.50.000200" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd-HH.mm.ss.SSSSSS" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;

Apply a ZoneId to get a ZonedDateTime object, thereby adjusting to view the moment through the wall-clock time used by the people of that particular region.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( ldt ) ;

Generally best to work with moments in UTC , unless you have a specific reason to use a time zone (such as presentation to user). So extract an Instant from your ZonedDateTime .

Instant instant = zdt.toInstant() ;

The Z at the end of an ISO 8601 compliant string means UTC, and is pronounced “Zulu”.

See this code run live at IdeOne.com .

input: 2018-12-31-12.30.50.000200

ldt: 2018-12-31T12:30:50.000200

zdt: 2018-12-31T12:30:50.000200+09:00[Asia/Tokyo]

instant: 2018-12-31T03:30:50.000200Z


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .

To learn more, see the Oracle Tutorial . And search Stack Overflow for many examples and explanations. Specification is JSR 310 .

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more .

Just a small supplement to Basil Bourque's clever and very informative answer .

  1. I know the date is in CET timezone.

I am sorry, this is not enough. Central European Time (CET) is the common term for quite many European and African(!) time zones the details of which differ. The European ones are generally at offset +01:00 during standard time and at +02:00 during summer (known as Central European Summer Time or CEST). The African ones are at +01:00 all year. For past dates, just a few decades back, some zones used summer time (DST), others didn't, some were at +00:00, +01:00 or +02:00, and further back in history many other offsets were used, generally not whole hours.

The future is even worse! It has been suggested that the European Union abandons summer time and leaves it to each member state whether they will use permanent standard time or permanent summer time, avoiding the time adjustments in spring and autumn. There is a power struggle going on about this, so we don't know whether it will happen, nor what each member state chooses. So even if you could tell me the exact time zone of your string from the other system (for example, Europe/Sarajevo), no one knows yet whether 2019-11-01-00.30.50.000200 — less than 7 months from now — will be at offset +01:00 or +02:00.

Link: European MPs vote to end summer time clock changes on BBC News.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM