【问题标题】:Time without date没有日期的时间
【发布时间】:2020-03-03 09:57:45
【问题描述】:

我从像 { "time": "03:00:00+01" } 这样的 json 格式的 PostgreSQL 服务器获取时区时间(没有日期组件)。我如何在 Android 中处理这个问题?有没有什么结构可以保持没有日期的时间?或者将其转换为纪元 Date 表示,即 Thu Jan 01 03:00:00 GMT+01:00 1970 是唯一好的解决方案?

【问题讨论】:

  • 有一些选项。你在 Android 上的时间需要做什么? OffsetTime from java.time, the modern Java date and time API 可能是代表时间的最佳类,但这取决于您的需求,所以请告诉我们它们是什么。
  • 我会指出,带有偏移量的时间实际上没有任何意义。如果没有日期的上下文,偏移量就没有用。

标签: android time date timeofday


【解决方案1】:

来自 java.time 和 ThreeTenABP 的 OffsetTime

OffsetTime 是一天中的时间,没有日期,并且与 UTC 有偏移。因此,它非常精确地从 JSON 中对字符串中的信息进行建模。所以我显然更喜欢它而不是Date。还因为 Date 类设计不佳且早已过时。

    String timeStringFromJson = "03:00:00+01";
    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ssX");
    OffsetTime parsedTime = OffsetTime.parse(timeStringFromJson, timeFormatter);
    System.out.println("Parsed time: " + parsedTime);

这个 sn-p 的输出是:

解析时间:03:00+01:00

作为一个对您而言可能或可能无关紧要的细节,字符串的偏移量被保留,这与 Date 可以做的相反,因为 Date 没有时区或偏移量。

问题:java.time 不需要 Android API 26 级吗?

java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。
  • 在非 Android 的 Java 6 和 7 中,获取 ThreeTen Backport,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

    【解决方案2】:

    您可以使用 SimpleDateFormat 将您的日期解析为 Date 对象,其模式如下:

    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
    
    try
        {
        Date date = format.parse("03:00:00+01", Locale.getDefault());
        Log.d( "debugDate", " date is: " + date );
        }
    catch (ParseException e)
        {
        e.printStackTrace();
        }
    

    输出:

    Thu Jan 01 03:00:00 GMT+01:00 1970
    

    如果你的日期结构变成“03:00:00+01:00”,你需要使用这个模式:

    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ssZ", Locale.getDefault());
    

    输出:

    Thu Jan 01 03:00:00 GMT+01:00 1970
    

    【讨论】:

    • 它仍然意味着将其转换为依赖于日期的对象。
    • 是的,这不是你想要的吗?
    • 不,问题本身中提到了此解决方案。我正在寻找可以处理时间与日期无关的东西。
    • 考虑不要使用早已过时且臭名昭著的麻烦SimpleDateFormat 和朋友,并将ThreeTenABP 添加到您的Android 项目中,以便使用java.time,现代Java 日期和时间API。使用起来感觉好多了。
    • 我收到了The method parse(String, ParsePosition) in the type SimpleDateFormat is not applicable for the arguments (String, Locale)。更正这一点,我在你的时区和我的时区得到了预期的输出,但是当我在美国/多伦多时区跑步时,我得到了date is: Thu Jan 01 03:00:00 EST 1970,尽管看起来相似,但时间点完全不同。
    【解决方案3】:

    您可以将字符串时间戳转换为自 Epoch 以来的毫秒数作为 long 值,然后存储/检索 long 值并将其转换回字符串时间戳,如下面在 main 中所做的那样。

    我假设您示例中的 +01 是欧洲中部时间。

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    import java.util.TimeZone;
    
    public class SDFTest {
    
        /**
        Global SimpleDateFormat
        */
        private static SimpleDateFormat sdf = null;
    
        public static void main(String[] args) {
            // Initialize the Simple Date Format;
            sdf = new SimpleDateFormat("HH:mm:ssX");
            // Ignore this if you need timestamps converted to your local TimeZone;
            sdf.setTimeZone(TimeZone.getTimeZone("CET"));
    
            // Say this is the supplied time String;
            String suppliedDate = "03:00:00+01";
    
            // Convert from String timestamp to long;
            long convertedToTimeStamp = getTimeStamp(suppliedDate);
            System.out.println(suppliedDate + " => " + convertedToTimeStamp + "ms");
    
            // Convert from long timestamp to String;
            String convertedBackToString = getDateString(convertedToTimeStamp);
            System.out.println(convertedToTimeStamp + "ms => " + convertedBackToString);
        }
    
    
        /**
        Converts String timestamp to the number of milliseconds since Epoch.
        */
        private static long getTimeStamp(String date_str) {
            try {
                Date date = sdf.parse(date_str);
                return date.getTime();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
    
        /**
        Converts long timestamp to String
        */
        private static String getDateString(long timestamp) {
            try {
                Date date = new Date(timestamp);
                return sdf.format(date);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    

    输出:

    由于 suppliedDate 中不存在 Date 组件,因此它永远不会重要。

    【讨论】:

      猜你喜欢
      • 2018-05-09
      • 2019-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多