【问题标题】:.net JSON Date format.net JSON 日期格式
【发布时间】:2011-09-28 21:27:13
【问题描述】:

作为 .net 服务的响应,我得到以下日期格式: /日期(1233323754523+0100)/

1233323754523 是时间戳格式的日期,但我不知道 +0100 是什么意思以及如何从 java 代码生成它?

谢谢

【问题讨论】:

  • 我强烈怀疑 +0100 是从 UTC 偏移一小时的时区。
  • UTC 偏移确实最有意义。
  • 谢谢 我想知道这是否有必要?没有它,结果是否相同——在序列化和反序列化时
  • 如果这些东西被发送到具有不同时区设置的机器上,你确实需要时区偏移量。如果所有使用它的计算机都在同一个时区,你可以忽略它,但这几乎意味着代码意外地正常工作。
  • 如果 1233323754523 是自 1970 年以来的毫秒数,那将是 2009-01-30 13:55:54 UTC;这就是你所期望的吗?将时区与 Unix 风格的时间戳结合起来对我来说似乎是一个非常糟糕的主意。 Unix 风格的时间戳本质上是 UTC。最好的方法是将时间存储为 UTC,然后在其上应用本地时区偏移以进行显示。也许 .net 做的不一样?

标签: java .net date


【解决方案1】:

我假设时间戳是 UTC 并且偏移量是所需本地时间的 UTC 偏移量。如果时间戳位于与 UTC 的给定偏移量中,则生成它的方式必须稍有不同。

在 Java 中生成它的可靠方法是使用 Joda-Time 库,它比默认的 java.util.Datejava.util.Calendar 类要好得多。

// A formatter that prints the timezone offset
DateTimeFormatter fmt = DateTimeFormat.forPattern("Z");

// The current date+time in the system default timezone.
DateTime dt = new DateTime();

// Create the result.
String result = "/Date(" + dt.getMillis() + fmt.print(dt) + ")/";

有点遗憾,DateTimeFormat 没有办法输出自纪元以来的毫秒数;这就是dt.getMillis() 字符串连接的必要条件。

要使用java.util 类生成相同的东西,看起来像这样:

// A formatter that prints the timezone offset
SimpleDateFormat df = new SimpleDateFormat("Z");    

// Current date+time in system default timezone.
Calendar now = Calendar.getInstance();

// Don't forget this if you use a timezone other than system default:
df.setTimeZone( now.getTimeZone() );

// Create the result
String result = "/Date(" now.getTimeInMillis() + df.format(now.getTime()) +")/";

它本质上与 Joda-Time 示例相同,但是您必须将时区从日历复制到日期格式化程序中是错误的主要来源。

【讨论】:

    【解决方案2】:

    第二个数字仅表示 DateTime 值应解释为本地日期时间(而不是 UTC),数字本身被忽略。这在http://msdn.microsoft.com/en-us/library/bb412170.aspx 文档的高级信息/日期时间线格式部分中进行了描述。

    【讨论】:

    【解决方案3】:

    这个问题有点过时了,但我认为仍然有一些人因为选择了出色的日期时间格式而感到头疼;)

    .NET Json 格式的 Java 中用于 Gson 的 DateTime 值的序列化和反序列化类型适配器 这对我来说已经工作了大约 2 年了。

    package x
    
    import java.lang.reflect.Type;
    import java.text.DecimalFormat;
    import java.util.Date;
    import java.util.TimeZone;
    import java.util.regex.Pattern;
    
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonParseException;
    import com.google.gson.JsonPrimitive;
    import com.google.gson.JsonSerializationContext;
    import com.google.gson.JsonSerializer;
    
    /**
     * Serialises and deserialises a string representing a date produced by a .NET web service.
     * 
     * @author Diego Frehner
     */
    public class TypeAdapterDate implements JsonSerializer<Date>, JsonDeserializer<Date> {
    
      /** Pattern for parsing date time values sent by a .NET web service. */
      private static Pattern pattern = Pattern.compile("^/Date\\([0-9\\+-]*\\)/$");
    
      private static DecimalFormat formatter = new DecimalFormat("#00.###");
    
      private static final long HOUR_IN_MILLISECOND = 60L * 60 * 1000;
    
      private static final String minusSign = "-";
    
      private static final String plusSign = "+";
    
      @Override
      public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext     context) throws JsonParseException {
        String value = json.getAsString();
        // example .NET web service return value: /Date(1302847200000+0200)/
        // milliseconds since midnight 1970 UTC + time zone offset of the server to UTC
        // GMT == UTC == UT it's all the same...afaik
        if (!pattern.matcher(value).matches()) {
          return null;
        }
        // get UTC millisecond value
        long utcMillisecond = Long.parseLong(value.substring(value.indexOf("(") + 1, value.indexOf(")") - 5));
    
        // new Date(long) takes milliseconds since 1970 in UTC
        return new Date(utcMillisecond);
      }
    
      @Override
      public JsonElement serialize(Date arg0, Type arg1, JsonSerializationContext arg2) {
        Date date = (Date) arg0;
    
        int zoneOffsetMillisecond = TimeZone.getDefault().getOffset(date.getTime());
        String sign = plusSign;
        if (zoneOffsetMillisecond < 0) { // negative offset
          sign = minusSign;
          zoneOffsetMillisecond *= -1;
        }
        int minute = (int) (zoneOffsetMillisecond % HOUR_IN_MILLISECOND);
        int hour = (zoneOffsetMillisecond / 1000 / 60 / 60);
        return new JsonPrimitive("/Date(" + date.getTime() + sign + formatter.format(hour) + formatter.format(minute) + ")/");
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 1970-01-01
      • 2018-05-13
      • 2012-05-24
      • 1970-01-01
      相关资源
      最近更新 更多