在Java/Android中使用公历时获取错误的时间戳值

在Java/Android中使用公历时获取错误的时间戳值,java,android,sqlite,date,datetime,Java,Android,Sqlite,Date,Datetime,我正在Android中使用时间选择器和日期选择器对话框。为了保存日期和时间我在Sqlite中使用整数数据类型。因此,我使用了一些实用函数将日期从日期选择器对话框转换为长(时间戳)格式,并将其转换回用户可读的日期。但不知怎的,他们给了我错误的结果 //Date Picker OnDateSetListener private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSet

我正在Android中使用时间选择器和日期选择器对话框。为了保存日期和时间我在Sqlite中使用整数数据类型。因此,我使用了一些实用函数将日期从日期选择器对话框转换为长(时间戳)格式,并将其转换回用户可读的日期。但不知怎的,他们给了我错误的结果

//Date Picker OnDateSetListener
 private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener(){

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        String dateText = getTimeString(year,monthOfYear,dayOfMonth);
        long date = Utility.getDateLong(year,monthOfYear,dayOfMonth);
        taskModel.setEndDate(date);
         endDateView.setText(dateText);
    }
};

 private String getTimeString(int year, int monthOfYear, int dayOfMonth){
    Log.i("set_date",monthOfYear+"");
    String yearText = String.valueOf(year);
    String monthText = String.valueOf(monthOfYear);
    String dayText = String.valueOf(dayOfMonth);
    return dayText+"/"+monthText+"/"+yearText;
}

//Utility Functions
//Getting long(TIMESTAMP) from DATE

public static long getDateLong(int year, int month, int day){
        Calendar calendar = new GregorianCalendar(year, month, day);
        Date date = calendar.getTime();
        long timeStamp = date.getTime();
        return timeStamp;
    }

//Converting TIMESTAMP to DATE
 public static String getDateFromLongValue(long d){
    Date date = new Date(d);
    //Calendar calendar = new GregorianCalendar();
    //calendar.setTimeInMillis(d);
    //return calendar.get(Calendar.DAY_OF_MONTH)+"/"+calendar.get(Calendar.MONTH)+"/"+calendar.get(Calendar.YEAR);

    DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
    String formattedDate = dateFormat.format(date);
    return formattedDate;
}
我输入的日期的时间戳弄错了。例如,如果输入的日期为2016年6月9日(“dd-MM-yyyy”),则转换后的长期值为-876215232,当转换回日期时,则为1969年12月22日

此外,当我从选择器中选择日期时,我的月份错了。i、 如果我选择了第九;七月,;2016年,我得到的是6英镑而不是7英镑。
请有人指出错误。

确保您传递给
GregorianCalendar
构造函数的当月值是基于0的,如文档所示。

确保传递给
GregorianCalendar
构造函数的当月值是基于0的。

tl;博士
  • 使用类。按您的预期计算月数:1-12
  • 存储为
    YYYY-MM-DD
    文本,而不是时间戳
细节 答案是正确的,您没有按照文档中告诉您的月份是以零为基础的计数(0-11),而不是以一为基础的计数(1-12)。疯狂的行为,是的。避免这些设计拙劣的旧日期时间类与最早版本的Java捆绑在一起的原因之一

java.time 相反,您应该使用内置于Java8和更高版本中的框架。这些类取代了旧的麻烦的日期时间类,如
java.util.date
&
java.util.Calendar
。看见大部分java.time功能都在中向后移植到Java6和Java7,并在中进一步适应Android

LocalDate
对于没有时间和时区的仅日期值,请使用类。月数是正常的,1-12

LocalDate localDate = LocalDate.of( 2016 , 1 , 31 );
或者使用方便的枚举

部分日期 您可以询问每个部分、年份、月份和月份的日期

int year = localDate.getYear();
int month = localDate.getMonthValue();
int dayOfMonth = localDate.getDayOfMonth();
时区 捕获当前日期时,请确保指定时区。在任何特定的时刻,全球各地的日期都会因地区而异

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneID );
ISO 8601 使用从-开始的毫秒计数对于仅日期值没有意义。考虑到SQLite具有,并且不支持SQL标准日期列,我建议存储一个表示日期值的字符串。具体来说,以ISO 8601标准定义的格式创建字符串。在解析和生成字符串时,java.time类默认使用此标准的格式。
YYYY-MM-DD
的标准格式恰好按字母顺序和时间顺序排序

String string = localDate.toString(); // 2016-01-31
LocalDate localDate = LocalDate.parse( string );
如果使用兼容JDBC 4.2的驱动程序,则可以通过
getObject
/
setObject
PreparedStatement
上传递
LocalDate

总结 因此,与旧类相比,
LocalDate
是:

  • 更符合逻辑(正常月份计数1-12)
  • 更易于使用字符串(直接解析/生成标准格式)
  • 真正表示仅限日期的值
tl;博士
  • 使用类。按您的预期计算月数:1-12
  • 存储为
    YYYY-MM-DD
    文本,而不是时间戳
细节 答案是正确的,您没有按照文档中告诉您的月份是以零为基础的计数(0-11),而不是以一为基础的计数(1-12)。疯狂的行为,是的。避免这些设计拙劣的旧日期时间类与最早版本的Java捆绑在一起的原因之一

java.time 相反,您应该使用内置于Java8和更高版本中的框架。这些类取代了旧的麻烦的日期时间类,如
java.util.date
&
java.util.Calendar
。看见大部分java.time功能都在中向后移植到Java6和Java7,并在中进一步适应Android

LocalDate
对于没有时间和时区的仅日期值,请使用类。月数是正常的,1-12

LocalDate localDate = LocalDate.of( 2016 , 1 , 31 );
或者使用方便的枚举

部分日期 您可以询问每个部分、年份、月份和月份的日期

int year = localDate.getYear();
int month = localDate.getMonthValue();
int dayOfMonth = localDate.getDayOfMonth();
时区 捕获当前日期时,请确保指定时区。在任何特定的时刻,全球各地的日期都会因地区而异

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneID );
ISO 8601 使用从-开始的毫秒计数对于仅日期值没有意义。考虑到SQLite具有,并且不支持SQL标准日期列,我建议存储一个表示日期值的字符串。具体来说,以ISO 8601标准定义的格式创建字符串。在解析和生成字符串时,java.time类默认使用此标准的格式。
YYYY-MM-DD
的标准格式恰好按字母顺序和时间顺序排序

String string = localDate.toString(); // 2016-01-31
LocalDate localDate = LocalDate.parse( string );
如果使用兼容JDBC 4.2的驱动程序,则可以通过
getObject
/
setObject
PreparedStatement
上传递
LocalDate

总结 因此,与旧类相比,
LocalDate
是:

  • 更符合逻辑(正常月份计数1-12)
  • 更易于使用字符串(直接解析/生成标准格式)
  • 真正表示仅限日期的值

公历月份从0开始到11,即1月是本日历年的第0个月。查看Java文档。这就是为什么你得到的是6而不是7,这是正确的。公历月份从0开始到11,也就是说,1月是这个日历年的第0个月。查看Java文档。这就是为什么您得到的是6而不是7,这是正确的。如果我以字符串形式存储LocalDateTime,如何使用它来执行日期操作,例如查找两个日期之间的时间间隔?如何使用它来执行日期操作