我在Android中使用时间选择器和日期选择器对话框。为了保存日期和时间,我在Sqlite中使用 INTEGER 数据类型。所以我做了一些实用工具函数,将 DATE 从日期选择器对话框转换为 LONG(TIMESTAMP)格式,并将其转换回用户可读 DATE 。但不知何故,他们给了我错误的结果。
//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;
}
我输入的DATE错误的TIMESTAMP。例如,如果输入的日期是09-06-2016(" dd-MM-yyyy"),则转换后的长值为-876215232,当转换回日期时为22-12-1969。
此外,当我从选择器中选择DATE时,我错了一个月。即如果我选择第9个; 7月; 2016年, monthOfYear 属性我得到的是6而不是7。 有人可以指出错误。
答案 0 :(得分:2)
确保您向GregorianCalendar
构造函数传递的月份值是基于0的here。
答案 1 :(得分:2)
LocalDate localDate = LocalDate.of( 2016 , 1 , 31 ); // 1 = January.
Answer by MPelletier是正确的,您没有按照文档告诉您月份是从零开始计数(0-11)而不是从1开始(1-12)。疯狂的行为,是的。 许多的原因之一是避免使用与最早版本的Java捆绑在一起的这些设计糟糕的旧日期时间类。
相反,您应该使用Java 8及更高版本中内置的java.time框架。这些类取代了旧的麻烦的日期时间类,如java.util.Date
& java.util.Calendar
。见Oracle Tutorial。许多java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。
LocalDate
对于没有时间且没有时区的仅限日期的值,请使用LocalDate
类。月份数字是理智的,1-12。
LocalDate localDate = LocalDate.of( 2016 , 1 , 31 );
或者使用方便的Month
枚举。
LocalDate localDate = LocalDate.of( 2016 , Month.JANUARY , 31 );
您可以查询每个部分,年,月和日期。
int year = localDate.getYear();
int month = localDate.getMonthValue();
int dayOfMonth = localDate.getDayOfMonth();
捕获当前日期时,请务必指定时区。对于任何特定时刻,日期在全球范围内因地区而异。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneID );
使用count-of-milliseconds-from - epoch对于仅限日期的值没有意义。鉴于SQLite有no true data types,并且没有任何东西可以支持SQL标准DATE列,我建议存储一个表示日期值的String。具体而言,以ISO 8601标准定义的格式创建String。在解析和生成字符串时,java.time类在默认情况下使用此标准的格式。 YYYY-MM-DD
的标准格式恰好按时间顺序按字母顺序排序。
String string = localDate.toString(); // 2016-01-31
LocalDate localDate = LocalDate.parse( string );
如果使用符合JDBC 4.2的驱动程序,您可以通过LocalDate
通过getObject
/ setObject
传递PreparedStatement
。
所以LocalDate
与旧类相比是: