【问题标题】:SimpleDateFormat with Timezone names in different languagesSimpleDateFormat 与不同语言的时区名称
【发布时间】:2016-03-02 09:26:03
【问题描述】:

我在尝试解析日期字符串时遇到了这个奇怪的问题,我已经确定了这一点:

具有一些英语语言环境的设备(模拟器):

Date.toString() 给出“2016 年 2 月 18 日星期四 13:25:22 GMT”

DateFormat newDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
d1 = newDateFormat.parse("Thu Feb 18 13:25:22 GMT 2016"); //works fine

使用德语区域设置的设备:

Date.toString() 给出“Thu Feb 18 13:25:22 MEZ 2016”(注意德语时区,而星期四仍然是星期四)

DateFormat newDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
d1 = newDateFormat.parse("Thu Feb 18 13:25:22 MEZ 2016"); //does not parse

DateFormat newDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.GERMAN);
d1 = newDateFormat.parse("Thu Feb 18 13:25:22 MEZ 2016"); //does not parse

DateFormat newDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
String s = "Thu Feb 18 13:25:22 MEZ 2016";
s.replace("MEZ", "CET");
d1 = newDateFormat.parse(s); //works fine, but doesn't seem very portable

所以我正在寻找一种方法让 SimpleDateFormat 完全忽略时区(这对我的应用程序来说很好,我在这里要做的唯一事情就是给“上次”一个时间差,这如果少于一天,将以小时为单位,但如果超过一天,则以几天或几周为单位,因此对于这个用例来说,时区并不重要),

或获取SimpleDateFormat 以了解设备语言中的时区的方法。

奖励积分是一种以独立于语言的方式保存日期的好方法,同时仍保留该时区中的时区和一天中的时间等信息。 (下次我升级数据库时)

【问题讨论】:

  • “以与语言无关的方式保存日期的好方法,同时仍保留该时区中的时区和一天中的时间等信息”iso8601 日期时间格式是您的答案跨度>
  • 在字符串 String s = "Thu Feb 18 13:25:22 MEZ 2016"; 你为什么要用 MEZ 替换 CET ,你为什么要更改那个时间的时区?这是错误的,因为该时间戳适用于 MEZ 时区,而您只是将其替换为 CET 时区
  • MEZ 和 CET 是同一个东西,只是用两种不同的语言
  • 您是否只是想弄清楚如何使用时区保存任何给定的 Date 对象,或者您实际上是否必须使用来自不同语言环境的日期/时间组件来解析这些字符串?
  • 好吧,由于开始编写应用程序时的设计选择不佳,这些字符串都在我的数据库中。现在我当然知道以更好的格式保存它们会是一个更好的主意,例如 +0100 之类的,但是要在我的数据库中更改它,我必须弄清楚如何正确解析它们(或蛮力字符串替换所有可能最终出现在数据库中的时区字符串......这就是我最终所做的,但我想我会为有同样问题的人保留这个问题)

标签: android date locale timestamp-with-timezone


【解决方案1】:

我这样做是为了以YYYY-MM-DD 格式获取当前日期。

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String CurrentDate = formatter.format(new Date());
Date current_date = formatter.parse(CurrentDate); //In case need the entire Date value

希望这会有所帮助!

【讨论】:

  • 不是,我特意问了关于保留时区信息的问题。无论如何,日期字符串就是它们现在的样子,我无法更改它们(至少不容易)
  • 所以您想将日期字符串从德语语言环境转换为美国,对吧?如果我错了,请纠正我。
  • @fifaltra -- 请查看我编辑的部分一次。我添加了formatter.setTimeZone(TimeZone.getTimeZone("UTC")); 行。让我知道这是否适合您。
  • 我想解析包含时区的 3 个字母的日期字符串,其中 3 个字母的字符串位于设备的语言环境中。
  • 使用更新后的代码,您将获得基于设备区域设置的 UTC 日期。
【解决方案2】:

为了得到你想要的结果(我相信它看起来像:Mi.März 15:15:58 02-03-16 MEZ)

我习惯了下面的代码:

public static final String DATE_FORMAT = "EEE MMM HH:mm:ss dd-MM-yy z";
private DateTimeFormatter mDateFormatter = DateTimeFormat.forPattern(DATE_FORMAT).withLocale(Locale.GERMAN);

/**
 * Get formatted Date as Human Readable String
 * @param dateTime the time to print
 * @return Date as String
 */
public String getFormattedDate(@NonNull DateTime dateTime) {
    return mDateFormatter.print(dateTime);
}

如果你想要一个时差,你可能想看看JodaTime (http://www.joda.org/joda-time/)。我自己用过,它提供了简单的时差接口(@98​​7654324@、Hours、Minutes、Months、Seconds、Weeks、Years)。

以 Unix 时间 (ISO 8601) 保存您的日期,这是您需要的所有信息。

【讨论】:

  • 计算时差不是我的问题,解析Date字符串才是问题。
【解决方案3】:

当你实例化 SimpleDateFormat 时,

DateFormat newDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");

SimpleDateFormat 有一个接受语言环境的构造函数,SimpleDateFormat(String) 构造函数现在已被弃用,你应该像这样使用接受语言环境的构造函数,

DateFormat df = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.getDefault());

现在,如果您使用此 df.parse(myDateString),则无需将字符串从 MEZ 替换为 CET,因为 SimpleDateFormat 知道您的语言环境会正确解析日期

【讨论】:

  • 我也是这么想的,但是Locale.getDefault()也因为某种原因没用
  • @fifaltra Locale.getDefault() 返回设备的默认区域设置,如果您的测试设备的默认区域设置为美国,那么带有德国区域设置的时间戳当然不起作用!在测试不同区域设置的时间戳之前尝试更改设备的区域设置
  • 显然我在德国设备上尝试了德国语言环境,试图将其强制为德国语言环境,因为 getDefault 也不起作用。
  • 但这就是android指定您应该如何使用日期api的方式,没有其他方法可以找出设备所在的语言环境
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
相关资源
最近更新 更多