我的字符串格式为 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日插入事件,并且相同。
所以我犯了错误????请告诉我正确的方法
答案 0 :(得分:2)
设置日期格式化程序使用的时区:调用setTimeZone方法 例如
curFormater.setTimeZone(TimeZone.getTimeZone("UTC"));
答案 1 :(得分:2)
java.util
日期时间 API 及其格式化 API SimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*。
请注意,没有时区的日期时间表示本地日期时间,对于不同的时区,例如可能会有所不同。今天,我的时区是 2021 年 5 月 31 日st,Europe/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.time
,Trail: 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"));
另外两个重要的注意事项:
MMMM
代替 MMM
作为完整的月份名称。* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。
答案 2 :(得分:1)
首先,您的日期模式错误,请使用dd MMMM yyyy
。 MMM
解析&返回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
。我希望它可以解决您的问题。