从Date获取毫秒时出现问题

时间:2010-11-25 10:03:48

标签: java android date

我的字符串格式为 25 November 2010 ,我正在尝试获取该日期的毫秒数,因为我已完成以下代码:

strDateSelcted = "25 November 2010" // Actually i am receiving date in this format
SimpleDateFormat curFormater = new SimpleDateFormat("dd MMM yyyy"); 
 try {
    Date dateObj = curFormater.parse(strDateSelcted);

        insertEventtoCalendar(dateObj.getTime());   // Actually insert an event onto the native calendar

  } catch (ParseException e) {
    // TODO Auto-generated catch block
        e.printStackTrace();
 } 

但是,当我尝试运行该应用程序时,它会在插入日期前一天创建一个事件,即2010年11月25日它将在2010年11月24日插入事件,2010年11月27日它将在2010年11月26日插入事件,并且相同。

所以我犯了错误????请告诉我正确的方法

5 个答案:

答案 0 :(得分:2)

设置日期格式化程序使用的时区:调用setTimeZone方法 例如

curFormater.setTimeZone(TimeZone.getTimeZone("UTC"));

答案 1 :(得分:2)

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*

请注意,没有时区的日期时间表示本地日期时间,对于不同的时区,例如可能会有所不同。今天,我的时区是 2021 年 5 月 31 日stEurope/London 而 2021 年 6 月 1st Australia/Sydney。因此,为了表示一个时刻(即 UTC 中时间轴上的瞬时点),Java 提供了一个名为 Instant 的类,您可以将其转换为其他日期时间类型,例如

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();

        LocalDate todayUK = now.atZone(ZoneId.of("Europe/London")).toLocalDate();
        LocalDate todaySydney = now.atZone(ZoneId.of("Australia/Sydney")).toLocalDate();
        System.out.println(todayUK);
        System.out.println(todaySydney);

        LocalDateTime nowUK = now.atZone(ZoneId.of("Europe/London")).toLocalDateTime();
        LocalDateTime nowSydney = now.atZone(ZoneId.of("Australia/Sydney")).toLocalDateTime();
        System.out.println(nowUK);
        System.out.println(nowSydney);
    }
}

输出:

2021-05-31
2021-06-01
2021-05-31T16:22:40.418214
2021-06-01T01:22:40.418214

因此,您需要选择一个时区。大多数数字操作基于 UTC(时区偏移,+00:00 小时)。

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("d MMMM u", Locale.ENGLISH);
        LocalDate date = LocalDate.parse("25 November 2010", dtf);
        ZonedDateTime zdt = date.atStartOfDay(ZoneOffset.UTC);
        Instant instant = zdt.toInstant();
        System.out.println(instant);

        long millis = instant.toEpochMilli();
        System.out.println("Milliseconds since January 1, 1970, 00:00:00 GMT: " + millis);
    }
}

输出:

2010-11-25T00:00:00Z
Milliseconds since January 1, 1970, 00:00:00 GMT: 1290643200000

示例输出中的 Z 是零时区偏移的 timezone designator。它代表祖鲁语并指定 Etc/UTC 时区(时区偏移为 +00:00 小时)。

现在,将 millis 传递给您的 insertEventtoCalendar

insertEventtoCalendar(millis);

注意:无论出于何种原因您需要一个 java.util.Date 的对象,您都可以从这个 Instant 获取它作为

Date date = Date.from(instant);

modern Date-Time API 中详细了解 java.timeTrail: Date Time*

您的代码出了什么问题?

您尝试在不设置时区的情况下解析日期字符串,因此,SimpleDateFormat 使用您的 JVM 时区来解析日期字符串,为您提供与 2010 年 11 月 25 日在您所在的时区。要解决此问题,请在解析之前将所需的 Timezone(例如 UTC)设置为 SimpleDateFormat 实例,即

SimpleDateFormat curFormater = new SimpleDateFormat("dd MMMM yyyy", Locale.ENGLISH);
curFormater.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

另外两个重要的注意事项:

  1. 使用 MMMM 代替 MMM 作为完整的月份名称。
  2. Never use SimpleDateFormat or DateTimeFormatter without a Locale

* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 2 :(得分:1)

首先,您的日期模式错误,请使用dd MMMM yyyyMMM解析&返回Nov(不是November)。

此外,由于日期字符串中没有提供毫秒,因此毫秒将设置为0

看到Jon Skeet更新了我的问题,可能是时区问题(正如他所提到的)。对不起有误。

测试代码:

/**
 * 
 */

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author The Elite Gentleman
 *
 */
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            String date = "25 November 2010";
            SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy");
            Date d = sdf.parse(date);
            System.out.println(d.getTime());
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

价值:1290636000000

答案 3 :(得分:0)

这几乎肯定是一个时区问题。检查您的SimpleDateFormat正在使用的时区以及您的手机用于显示活动的时区。

出于诊断目的,我建议您记录dateObj.getTime()的结果,然后您可以检查完全在桌面计算机上的含义。

答案 4 :(得分:0)

当您使用Locale.getDefault()时使用SimpleDateFormat。我希望它可以解决您的问题。