2017-06-05 68 views
3

我要打印的當前日期這種格式2017/06/05>Year/Month/Day 在它的旁邊,這種格式+3如何獲取當前日期和數字格式的時區

我用這個代碼當前時區

String DateToday = DateFormat.getDateInstance().format(new Date()); 
String TZtoday = DateFormat.getTimeInstance().getTimeZone().getDisplayName(); 
txt.setText(DateToday + " | "+ TZtoday); 

但是,它這樣表示:

2017年6月5日|阿拉伯標準時間

我希望它是這樣的:

2017年6月5日| +3

+1

如果偏移量不是整小時數,您希望發生什麼? –

+0

@ OleV.V。沒有得到什麼意思呢? –

+1

例如,假設「Asia/Kathmandu」的區域偏移量爲+05:45。這應該如何打印?如果答案是「不關心」,我建議你在這種情況下拋出異常。 –

回答

2
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd | X"); 
System.out.println(sdf.format(new Date())); 

靠攏,但時區印有前導零:

2017/06/05 | +03 

我想你可以從時間區域中刪除前導零,如果你需要:

SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd"); 
SimpleDateFormat zone = new SimpleDateFormat("ZZZZZ"); // = +03:00 
String tz = zone.format(new Date()).split(":")[0] 
    .replaceAll("^(\\+|-)0", "$1"); // = +3 
System.out.println(sdf.format(new Date()) + " | " + tz); 

這給:

2017/06/05 | +3 
+0

日期顯示正確:D,但只有當我在格式中移除X時纔會顯示錯誤,因爲它會以錯誤java.lang的形式崩潰應用程序。IllegalArgumentException:未知模式字符'X'' –

+0

@Sam您正在使用java.text.SimpleDateFormat嗎?也許'X'是在Java 8中添加的。不,我剛剛檢查過,它也在Java 7中。 –

+0

@Sam根據[Android文檔](https://developer.android.com/reference/java/text/SimpleDateFormat.html),它也支持Android。你在用什麼? –

0

使用以下邏輯來獲取所需的日期格式。

public static void main(String[] args) { 

     Calendar cal = Calendar.getInstance(); 
     cal.add(Calendar.DATE, 1); 
     SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd"); 
     System.out.println(cal.getTime()); 
// Output "Wed Sep 26 14:23:28 EST 2012" 

     String formatted = format1.format(cal.getTime()); 
     String formattedmain=formatted.replace("-","/"); 
     System.out.println(formatted); 
     // Output "2012-09-26" 
     System.out.println(formattedmain); 

//Output :- 2017/06/06 


    } 
+2

這是錯誤的格式。 OP詢問斜槓,而不是破折號和時區偏移量。 –

+0

等待我會根據需要做斜線修改,這不是什麼大問題 –

+0

而對於偏移量,在這裏添加b的時間量cal.add(Calendar.DATE,1);在這個瞬間1給出1天的偏移量在那裏。 –

3

我知道你是在Android上,我知道那是什麼提供在Android內置就像DateFormatSimpleDateFormatDateCalendar的早已過時的類。但我仍然說,如果你正在做日期和/或時間和/或時區的事情,你應該認真考慮跳過這些課程並轉向他們的現代替代品。這將要求你得到ThreeTenABP。那麼我建議是這樣的:

2017/06/05 | +2 

結果在亞洲/加德滿都時區可能不正是你想要的東西:我的電腦上

ZonedDateTime date = ZonedDateTime.now(ZoneId.systemDefault()); 
    String tzToday = date.format(DateTimeFormatter.ofPattern("uuuu/MM/dd | x")); 
    tzToday = tzToday.replaceFirst("(?<=\\+|-)0", ""); 

結果

2017/06/05 | +545 

你可能會認爲我的代碼片段並不比使用舊的類更有優勢。當我說有這麼多的老班給你帶來負面的驚喜時,你可能會說我的話,所以你可以越早開始使用新的,越好。或者,你可能會在格式模式字符串中輸入一個拼寫錯誤,例如,注意你如何得到一個令人驚訝的結果,而沒有發現任何錯誤的跡象,而新的類將嘗試將一個有意義的錯誤信息放在一起。

需要注意的另一個細節是我正在讀取系統時鐘和JVM的時區一次(將時區傳遞迴now()以確保它在該時間使用)。您的代碼在問題中首先格式化日期,然後讀取時區。如果有人在兩者之間更改時區,則結果將不一致。非常不可能,但這也意味着很難有人能夠弄清楚發生了什麼。

正則表達式中的(?<=\\+|-)是一個倒序:我將用+-替換0,後面帶有空字符串。我徒勞地搜索一種方法來根據需要格式化區域偏移量,如+3,所以我使用了replaceFirst方法。

更多鏈接:How to use ThreeTenABP in Android Project

+2

好吧,我在轉移到Android之前一直是一個java開發人員,所以我會確保我的下一次Times/Dates實現將與ThreeTenABP一起使用,非常感謝建議。! –

1

作爲@Ole V.V.'s answer的補充,我發現了另一種使用ThreeTenABP的方法,但不需要正則表達式替換(儘管我不認爲它更簡單,下面更多)。

使用DateTimeFormatterBuilder可以使用HashMap將偏移值映射到String。因此,對於整個抵消時間(如+03:00),可以將相應的值映射到字符串+3等等。

唯一的問題是,ZoneOffset精度。最小值和最大值分別爲UTC-18:00:00UTC+18:00:00。所以所有可能的值是UTC-18:00:00,UTC-17:59:59,UTC-17:59:58等等。格式化程序需要映射所有可能的值(否則它將顯示偏移量的秒數值),因此地圖將會有超過120K個條目!

爲了建立這個地圖,我做了2個循環:

  • 第一個循環映射整個小時的偏移量(+01:00+1-02:00-2等)
  • 第二個循環的所有映射其它值(它們保持不變):
    • 整個小時> = 10(如+10:00
    • 未整小時(如+05:30

的代碼來創建格式化:

// builds a hashmap to map all offset values 
Map<Long, String> map = new HashMap<>(); 

// First loop: Map whole hours from 1 to 9 and from -9 to -1 
// So a "+01:00" offset is displayed as "+1" 
for (int i = 1; i <= 9; i++) { 
    long seconds = ZoneOffset.ofHours(i).getTotalSeconds(); 
    // 1 hour offset maps to "+1" and so on 
    map.put(seconds, "+" + i); 
    // -1 hour offset maps to "-1" and so on 
    map.put(-seconds, "-" + i); 
} 

// second loop: Need to map all other possible values for not-whole hours 
// offsets like "+10:00" and "+01:30" are not changed 
int minOffset = ZoneOffset.MIN.getTotalSeconds(); 
int maxOffset = ZoneOffset.MAX.getTotalSeconds(); 
for (long i = minOffset; i <= maxOffset; i++) { 
    // the map already contains whole hours, don't need to overwrite the values 
    if (!map.containsKey(i)) { 
     // uses default String representation (like "+05:30") 
     map.put(i, ZoneOffset.ofTotalSeconds((int) i).getId()); 
    } 
} 

// create the formatter 
DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
       // year/month/day and the "|" 
       .appendPattern("uuuu/MM/dd | ") 
       // use the map of custom values (offset will use the values in the map) 
       .appendText(ChronoField.OFFSET_SECONDS, map) 
       // create formatter 
       .toFormatter(); 

一些測試:

LocalDateTime dt = LocalDateTime.of(2017, 5, 1, 10, 0); 
ZonedDateTime z = ZonedDateTime.of(dt, ZoneId.of("America/Sao_Paulo")); // UTC-03:00 
System.out.println(formatter.format(z)); // 2017/05/01 | -3 

// just picking some timezone in Arabia Stardard Time 
// (there are more than one timezone in AST: https://en.wikipedia.org/wiki/UTC%2B03:00#Arabia_Standard_Time) 
// I don't know in which one you are 
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Qatar")); // UTC+03:00 
System.out.println(formatter.format(z)); // 2017/05/01 | +3 

// 2-digit offset 
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Vladivostok")); // UTC+10:00 
System.out.println(formatter.format(z)); // 2017/05/01 | +10:00 

// not whole hour 
z = ZonedDateTime.of(dt, ZoneId.of("Asia/Kathmandu")); // UTC+05:45 
System.out.println(formatter.format(z)); // 2017/05/01 | +05:45 

的輸出是:

2017年5月1日| -3
2017/05/01 | +3
2017/05/01 | +10:00
2017/05/01 | +05:45


注:

  • 我不知道是否有120K條目地圖比使用正則表達式(這是由你來決定)更好。這種方法創建一個大的地圖,但至少不需要輸出後處理(不知道這是否合理取捨)
  • 如果要將整小時偏移> = 10顯示爲+10+11和依此類推,只需將第一個for循環更改爲for (int i = 1; i <= maxOffsetYouWant; i++) - 只需提醒maximum possible value for maxOffsetYouWant is 18即可。
+1

哇,這是一個非常有趣的方法來解決這個問題,謝謝你,儘管對我來說完全理解起來更加複雜。所以現在我會堅持舊的Java類解決方案,因爲我的應用程序的受衆不會超過+3時區。但再次感謝您的幫助 –

+0

事實上,我必須承認,針對這一特定案例的解決方案比我想要的更復雜。但除此之外,你應該花一些時間學習新的API。它比'Date'和'Calendar'好得多,它真的值得學習。 – 2017-06-06 11:48:00

+1

我肯定;) –

相關問題