没有日期的时间

Time without date

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

您可以使用具有以下模式的 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

OffsetTime 来自 java.time 和 ThreeTenABP

OffsetTime 是一天中没有日期但与 UTC 有偏差的时间。因此,它非常精确地模拟了来自 JSON 的字符串中的信息。所以我显然更喜欢它而不是 Date。也因为 Date class 设计不佳且早已过时。

    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);

此片段的输出是:

Parsed time: 03:00+01:00

作为一个对你来说可能重要也可能不重要的细节,字符串的偏移量被保留,这与 Date 可以做的相反,因为 Date 没有时区或偏移量。

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

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

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置现代 API。
  • In-Android Java 6 和 7 获得 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接) .
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接

您可以将字符串时间戳转换为自纪元以来的毫秒数作为 long 值,然后 store/retrieve 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 组件,所以这无关紧要。