2012-09-19 52 views
17

Tôi có dấu thời gian ở dạng UTC và tôi muốn chuyển đổi múi giờ thành giờ địa phương mà không cần sử dụng cuộc gọi API như TimeZone.getTimeZone("PST"). Làm thế nào chính xác là bạn phải làm điều này? Tôi đã sử dụng đoạn mã sau mà không có nhiều thành công: giá trị đầu vàoJava: Làm thế nào để bạn chuyển đổi dấu thời gian UTC thành giờ địa phương?

private static final SimpleDateFormat mSegmentStartTimeFormatter = new  SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 

Calendar calendar = Calendar.getInstance(); 

    try { 
     calendar.setTime(mSegmentStartTimeFormatter.parse(startTime)); 
    } 
    catch (ParseException e) { 
     e.printStackTrace(); 
    } 

    return calendar.getTimeInMillis(); 

mẫu: [2012-08-15T22:56:02.038Z]

nên trở lại tương đương với [2012-08-15T15:56:02.038Z]

Trả lời

38

Date không có cửa hàng múi giờ và trong nội bộ trong UTC. Chỉ khi một ngày được định dạng là hiệu chỉnh múi giờ được áp dụng. Khi sử dụng DateFormat, nó mặc định theo múi giờ của JVM đang chạy. Sử dụng setTimeZone để thay đổi khi cần thiết.

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 

Date date = utcFormat.parse("2012-08-15T22:56:02.038Z"); 

DateFormat pstFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 
pstFormat.setTimeZone(TimeZone.getTimeZone("PST")); 

System.out.println(pstFormat.format(date)); 

này in 2012-08-15T15:56:02.038

Lưu ý rằng tôi rời ra 'Z' theo định dạng PST vì nó chỉ ra UTC. Nếu bạn chỉ cần đi với Z sau đó sản lượng sẽ được 2012-08-15T15:56:02.038-0700

+5

Làm mát nó thực sự hiệu quả. Tôi đã có thể nhận múi giờ mặc định của thiết bị Android bằng cách gọi TimeZone.getDefault(). –

0

Dưới đây là một giải pháp thay đổi đơn giản

public String convertToCurrentTimeZone(String Date) { 
      String converted_date = ""; 
      try { 

       DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
       utcFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 

       Date date = utcFormat.parse(Date); 

       DateFormat currentTFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
       currentTFormat.setTimeZone(TimeZone.getTimeZone(getCurrentTimeZone())); 

       converted_date = currentTFormat.format(date); 
      }catch (Exception e){ e.printStackTrace();} 

      return converted_date; 
    } 


    //get the current time zone 

    public String getCurrentTimeZone(){ 
      TimeZone tz = Calendar.getInstance().getTimeZone(); 
      System.out.println(tz.getDisplayName()); 
      return tz.getID(); 
    } 
+0

Điều này trả về thời gian UTC, mà tôi muốn chuyển đổi thành giờ địa phương !!!! – ArhatBaid

2

Sử dụng ngày Java & thời gian API hiện đại, và điều này rất đơn giản:

String inputValue = "2012-08-15T22:56:02.038Z"; 
    Instant timestamp = Instant.parse(inputValue); 
    ZonedDateTime losAngelesTime = timestamp.atZone(ZoneId.of("America/Los_Angeles")); 
    System.out.println(losAngelesTime); 

Bản in này

2012-08-15T15:56:02.038-07:00[America/Los_Angeles] 

Điểm cần lưu ý:

  • Có một lỗi nhỏ trong mong đợi của bạn. Z trong dấu thời gian của bạn có nghĩa là UTC, còn được gọi là thời gian Zulu. Vì vậy, trong giá trị thời gian địa phương của bạn, không nên có Z. Thay vào đó bạn sẽ muốn có một giá trị trả lại như ví dụ 2012-08-15T15:56:02.038-07:00, vì chênh lệch giờ là -7 giờ thay vì Z.
  • Tránh chữ viết tắt của ba múi giờ. Chúng không được tiêu chuẩn hóa và do đó thường không rõ ràng. PST, ví dụ, có thể có nghĩa là Giờ chuẩn Philppine, Giờ chuẩn Thái Bình Dương hoặc Giờ chuẩn Pitcairn (mặc dù S viết tắt thường là thời gian mùa hè (nghĩa là DST)). Nếu bạn dự định Giờ chuẩn Thái Bình Dương, đó không phải là múi giờ, vì vào mùa hè (nơi dấu thời gian mẫu của bạn rơi) Giờ ban ngày Thái Bình Dương được sử dụng. Thay vì chữ viết tắt, hãy sử dụng ID múi giờ theo định dạng vùng/thành phố như trong mã của tôi.
  • Dấu thời gian thường được xử lý tốt nhất là Instant đối tượng. Chỉ chuyển đổi thành ZonedDateTime khi bạn có nhu cầu, như cho bản trình bày.

Câu hỏi: Tôi có thể sử dụng API hiện đại với phiên bản Java của mình không?

Nếu sử dụng ít nhất Java , bạn có thể.

  • Trong Java 8 trở lên, API mới được tích hợp sẵn.
  • Trong Java 6 và 7 nhận được the ThreeTen Backport, cổng sau của các lớp mới (đó là ThreeTen cho JSR-310, nơi API hiện đại được xác định lần đầu).
  • Trên Android, sử dụng phiên bản Android của ThreeTen Backport. Nó được gọi là ThreeTenABP và tôi nghĩ rằng có một lời giải thích tuyệt vời trong số this question: How to use ThreeTenABP in Android Project.
Các vấn đề liên quan