将丹麦语设置为VM参数时,org.joda.time.DateTime的toString()方法失败

时间:2017-09-19 14:07:43

标签: java datetime jodatime datetime-format

import java.text.SimpleDateFormat;
import java.util.Locale;

import org.joda.time.DateTime;
import org.joda.time.Interval;

public class JordaTimeTest {

    public static void main(String[] args) {
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
        SimpleDateFormat dateFormat = dateFormat1;

        Interval interval = new Interval(1499628963860L, 1511809983860L);
        DateTime start = new DateTime(interval.getStart());
        DateTime end = new DateTime(interval.getEnd());

        System.out.println(start.toString(dateFormat.toLocalizedPattern()));
    }
}

我按照How to set eclipse console locale/language

中指定的方式进行操作

我使用-Duser.language=da -Duser.country=DK作为VM参数。我得到了例外:

  

java.lang.IllegalArgumentException:非法模式组件:tt

有什么想法解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

将区域设置设置为 da_DK 时,方法toLocalizedPattern会在Joda-Time中返回EEE tt/MM HH:mmtt is not a recognized pattern

如果希望使用特定语言输出,则无需更改JVM默认语言环境(因为这会影响在同一JVM中运行的所有其他应用程序)。相反,您可以创建org.joda.time.format.DateTimeFormatter并仅在格式化程序中设置区域设置:

DateTimeFormatter fmt = DateTimeFormat
    // set pattern
    .forPattern("EEE dd/MM HH:mm")
    // set locale
    .withLocale(new Locale("da", "DK"));
System.out.println(fmt.print(start));
System.out.println(fmt.print(end));

这将输出:

  

sø09/ 07 16:36
  ma 27/11 17:13

请注意,输出取决于JVM默认时区:1499628963860对应于UTC 2017-07-09T19:36:03.860Z,在我的JVM默认时区(America/Sao_Paulo)中为16:36。在您的机器中,值将不同。

如果您想指定时区,可以创建日期,如:

// create date in UTC
DateTime start = new DateTime(interval.getStart(), DateTimeZone.UTC);

现在DateTime是UTC格式,因此输出为sø 09/07 19:36

您还可以使用DateTimeZone.forID("zonename")设置为特定时区,其中zonename是有效的IANA timezone name(始终采用Region/City格式,例如America/Sao_PauloEurope/Berlin)。 避免使用3个字母的缩写(例如CSTPST),因为它们是ambiguous and not standard

您可以致电DateTimeZone.getAvailableIDs()获取可用时区列表(并选择最适合您系统的时区)。

正如@JB Nizet's comment中所述,没有必要使用SimpleDateFormat(因为它旨在与java.util.Datejava.util.Calendar一起使用。)

Java新日期/时间API

Joda-Time处于维护模式,正在被新的API取代,因此我不建议使用它来启动新项目。即使在joda's website中它也说:“请注意,Joda-Time被认为是一个很大程度上”完成“的项目。没有计划大的增强。如果使用Java SE 8,请迁移到java.time(JSR) -310)。“即可。

如果您不能(或不想)从Joda-Time迁移到新API,则可以忽略此部分。

如果您使用的是 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs

如果您使用的是 Java 6或7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,您还需要ThreeTenABP(更多关于如何使用它here)。

以下代码适用于两者。 唯一的区别是包名称(在Java 8中为java.time,在ThreeTen Backport(或Android的ThreeTenABP)中为org.threeten.bp),但类和方法名称是相同的

您无需创建间隔并从中获取开始和结束。您可以直接创建日期:

// use system default timezone
ZoneId zone = ZoneId.systemDefault();
ZonedDateTime start = Instant.ofEpochMilli(1499628963860L).atZone(zone);
ZonedDateTime end = Instant.ofEpochMilli(1511809983860L).atZone(zone);

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE dd/MM HH:mm", new Locale("da", "DK"));
System.out.println(start.format(fmt));
System.out.println(end.format(fmt));

输出结果为:

  

sø09/ 07 16:36
  ma 27/11 17:13

如果要转换为其他时区(而不是JVM默认值),可以使用ZoneId.of("zonename")ZoneOffset.UTC来使用UTC。

答案 1 :(得分:0)

SimpleDateFormat dateFormat1 = new SimpleDateFormat("EEE dd/MM HH:mm", Locale.getDefault());
SimpleDateFormat dateFormat = dateFormat1;
DateFormatSymbols dfs = dateFormat.getDateFormatSymbols();
dfs.setLocalPatternChars("GyMdkHmsSEDFwWahKzZ");
dateFormat.setDateFormatSymbols(dfs);
Interval interval = new Interval(1499628963860L, 1511809983860L);
DateTime start = new DateTime(interval.getStart());
DateTime end = new DateTime(interval.getEnd());

System.out.println(start.toString(dateFormat.toLocalizedPattern()));

这是解决问题的另一种方法

其字符集用于解释日期和时间

ex :-  y = year 
d = day
M = month 
m = minutes etc 
在DK中的

使用的是Y和u的使用 但是Joda时间不支持t和你