英文:
Joda Time toDate() wrong result
问题
我正在使用这段代码:
date - 来自 DatePicker 的日期对象,格式为字符串 Thu Sep 10 00:00:00 GMT+03:00 2020
mDate = DateTime(date)
           .withHourOfDay(0)
           .withMinuteOfHour(0)
           .withSecondOfMinute(0)
           .withMillisOfSecond(0)
           .toDate()
结果为:
mDate - Wed Sep 09 03:00:00 GMT+03:00 2020
这段代码有什么问题吗?
英文:
I am using this code:
date - Date object from DatePicker, as string Thu Sep 10 00:00:00 GMT+03:00 2020
mDate = DateTime(date)
           .withHourOfDay(0)
           .withMinuteOfHour(0)
           .withSecondOfMinute(0)
           .withMillisOfSecond(0)
           .toDate()
The result
mDate - Wed Sep 09 03:00:00 GMT+03:00 2020
What wrong with this?
答案1
得分: 2
你没有正确地将 DateTime 对象转换为 java.util.Date。一个正确的方法是从 DateTime 对象中获取毫秒数,并使用这些毫秒数初始化 java.util.Date。
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Main {
    public static void main(String[] args) {
        // 定义日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");
        // 来自DatePicker的日期时间字符串
        String strDateTime = "Thu Sep 10 00:00:00 GMT+03:00 2020";
        DateTime dateTime = DateTime.parse(strDateTime, formatter);
        System.out.println(dateTime);
        // 从 1970-01-01T00:00:00Z 开始的毫秒数
        long millis = dateTime.getMillis();
        System.out.println(millis);
        Date mDate = new Date(millis);
        // 在默认时区 (BST) 中显示 java.util.Date 对象
        System.out.println(mDate);
        // 在不同的时区下和使用自定义格式显示 java.util.Date
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+3"));
        System.out.println(sdf.format(mDate));
    }
}
输出:
2020-09-09T21:00:00.000Z
1599685200000
Wed Sep 09 22:00:00 BST 2020
Thu Sep 10 00:00:00 GMT+03:00 2020
注意: java.util.Date 不表示日期/时间对象。它只表示从 1970-01-01T00:00:00Z 开始的毫秒数。它没有任何时区或区域偏移信息。当你打印它时,Java 使用你的 JVM 的时区来生成字符串。如果你想在其他时区中打印它,可以使用上面示例中展示的 SimpleDateFormat。
我建议你从过时且容易出错的 java.util 日期时间 API 和 SimpleDateFormat 切换到现代的 java.time 日期时间 API 和相应的格式化 API(位于 java.time.format 包中)。从 教程: 日期时间 中了解更多关于现代日期时间 API 的信息。如果你的 Android API 版本仍不符合 Java 8,可以查看 https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project 和 通过 desugaring 可用的 Java 8+ API。
下表显示了现代日期时间类的概览:

英文:
You are not converting the DateTime object to java.util.Date correctly. A correct way is to get the milliseconds from DateTime object and initialize the java.util.Date with the milliseconds.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class Main {
	public static void main(String[] args) {
		// Define formatter
		DateTimeFormatter formatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zZ yyyy");
		// Date-time string from DatePicker
		String strDateTime = "Thu Sep 10 00:00:00 GMT+03:00 2020";
		DateTime dateTime = DateTime.parse(strDateTime, formatter);
		System.out.println(dateTime);
		// No. of milliseconds from the epoch of 1970-01-01T00:00:00Z 
		long millis = dateTime.getMillis();
		System.out.println(millis);
		Date mDate = new Date(millis);
        // Display java.util.Date object in my default time-zone (BST)
		System.out.println(mDate);
        //Display java.util.Date in a different time-zone and using custom format
		SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
		sdf.setTimeZone(TimeZone.getTimeZone("GMT+3"));
		System.out.println(sdf.format(mDate));
	}
}
Output:
2020-09-09T21:00:00.000Z
1599685200000
Wed Sep 09 22:00:00 BST 2020
Thu Sep 10 00:00:00 GMT+03:00 2020
Note: java.util.Date does not represent a Date/Time object. It simply represents the no. of milliseconds from the epoch of 1970-01-01T00:00:00Z. It does not have any time-zone or zone-offset information. When you print it, Java prints the string obtained by applying the time-zone of your JVM. If you want to print it in some other timezone, you can do so using the SimpleDateFormat as shown above.
I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time. If your Android API level is still not compliant with Java8, check https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project and Java 8+ APIs available through desugaring.
The following table shows an overview of modern date-time classes:

通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论