如何增加一个月的毫秒数? [英] How can I add one month to change into the milliseconds?
问题描述
我在将当前时间更改为毫秒时遇到问题,该毫秒数是在设置日期和时间之前一个月显示的.我知道计算机从0开始的月份,我该如何解决该问题?首先,我将日期和时间转换为String
,然后将String
转换为SimpleDateFormat
中的日期,然后将日期转换为Long
.
例如:当用户输入日期"2018/2/14 11:18"(AM)时,转换为long的日期为"1515899940000".
这是我的代码:
private void setDateField() {
Calendar c = Calendar.getInstance();
int yy = c.get(Calendar.YEAR);
int mm = c.get(Calendar.MONTH);
int dd = c.get(Calendar.DAY_OF_MONTH);
c.set(Calendar.MONTH, mm);
c.set(Calendar.DAY_OF_MONTH, dd);
c.set(Calendar.YEAR, yy);
DatePickerDialog datePickerDialog = new DatePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog ,new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int selectedYear, int selectedMonth, int selectedDate) {
year = selectedYear;
month = selectedMonth;
day = selectedDate;
date_time = year + "/" + (month + 1) + "/" + day;
timePicker();
}
},year, month, day);
datePickerDialog.getDatePicker().setMinDate(c.getTimeInMillis());
datePickerDialog.show();
}
private void timePicker(){
// Get Current Time
final Calendar c = Calendar.getInstance();
hours = c.get(Calendar.HOUR_OF_DAY);
minutes = c.get(Calendar.MINUTE);
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog,new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,int minute) {
hours = hourOfDay;
minutes = minute;
string_date = date_time+" "+format(hours) + ":" +format(minutes) ;
addtime.setText(string_date);
Log.e("JEJEJEJE",string_date);
SimpleDateFormat f = new SimpleDateFormat("yyyy/mm/dd HH:mm");
try {
Date d = f.parse(string_date);
milliseconds = d.getTime();
Log.e("LONGGGGGGG", String.valueOf(milliseconds));
} catch (ParseException e) {
e.printStackTrace();
}
}
}, hours, minutes, true);
timePickerDialog.show();
}
我建议:首先,代替您的变量(字段?),只是year
,month
,day
,hours
和minutes
声明
private LocalDate date;
private LocalTime time;
private long milliseconds;
(保留milliseconds
变量,因为您希望在此处获得结果.)
在onDateSet
中,可以通过以下方式为date
分配一个值:
date = LocalDate.of(selectedYear, selectedMonth + 1, selectedDate);
正如您所说,这是我们考虑的地方,日期选择器的selectedMonth
是从0开始的,而LocalDate
是从1开始的数月.
现在您的timePicker
方法变为
private void timePicker(){
// Get Current Time
time = LocalTime.now(ZoneId.systemDefault());
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(this,
android.R.style.Theme_Holo_Light_Dialog,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,int minute) {
time = LocalTime.of(hourOfDay, minute);
milliseconds = date.atTime(time)
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
Log.e("LONGGGGGGG", String.valueOf(milliseconds));
}
},
time.getHour(),
time.getMinute(),
true);
timePickerDialog.show();
}
您使事情变得非常复杂.我建议:
- 请勿在业务逻辑中使用字符串作为日期或时间,而应使用日期和时间对象.这也意味着您不需要像
SimpleDateFormat
这样的格式化程序(我可能会添加它,这是非常麻烦的,因此最好不用它). - 使用现代Java日期和时间API
java.time
.与老式的日期和时间类(如Calendar
)相比,它要好得多.
以上两个片段中的两点并存.而且据我所知,您没有使用setDateField
中的Calendar
对象(c
),只需将其删除并全部使用.
您的代码出了什么问题?
罪魁祸首是您的SimpleDateFormat
.尝试像这样使用它:
SimpleDateFormat f = new SimpleDateFormat("yyyy/mm/dd HH:mm");
System.out.println(f.parse("2018/04/17 12:45"));
在我的计算机上打印
Wed Jan 17 12:45:00 CET 2018
无论字符串中的内容是什么,它都会打印一月的日期.这是因为您尝试使用小写mm
一个月. mm
用于分钟(也可以正确使用),月份是大写MM
.因此,格式化程序根本无法解析一个月,而为您的日期指定默认月份,即一年中的第一个月,即一月.当然,一月份的这个日期也是进入毫秒值的时间.
问题:我可以在Android上使用java.time
吗?
是的,您可以在Android上使用java.time
.使用它只需要Java 6 .
- 在Java 8和更高版本以及更新的Android版本中,新的API都是内置的.
- 在Java 6和7中,获得了ThreeTen反向端口,这是现代类的反向端口(JSR 310的ThreeTen,首次描述了现代API).
- 在较旧的Android上,使用Android版本的ThreeTen Backport.称为ThreeTenABP.确保从包
org.threeten.bp
和子包中导入日期和时间类.
链接
- Oracle教程:日期时间,说明了如何使用
java.time
. - ThreeTen Backport项目
- ThreeTenABP ,ThreeTen Backport的Android版本
- 问题:如何在Android Project中使用ThreeTenABP ,非常详尽的解释.
- Java规范请求(JSR)310 .
I have a problem changing the current time into milliseconds, the milliseconds shown one month before the set date and time. I know the computer starts the months at 0, how can I solve the problem? First, I transfer the date and the time into String
, then I convert the String
into date in SimpleDateFormat
, and then I convert the date into Long
.
For example: When the user enter the date "2018/2/14 11:18 "(AM), the date convert to long is "1515899940000" .
Here is my code:
private void setDateField() {
Calendar c = Calendar.getInstance();
int yy = c.get(Calendar.YEAR);
int mm = c.get(Calendar.MONTH);
int dd = c.get(Calendar.DAY_OF_MONTH);
c.set(Calendar.MONTH, mm);
c.set(Calendar.DAY_OF_MONTH, dd);
c.set(Calendar.YEAR, yy);
DatePickerDialog datePickerDialog = new DatePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog ,new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int selectedYear, int selectedMonth, int selectedDate) {
year = selectedYear;
month = selectedMonth;
day = selectedDate;
date_time = year + "/" + (month + 1) + "/" + day;
timePicker();
}
},year, month, day);
datePickerDialog.getDatePicker().setMinDate(c.getTimeInMillis());
datePickerDialog.show();
}
private void timePicker(){
// Get Current Time
final Calendar c = Calendar.getInstance();
hours = c.get(Calendar.HOUR_OF_DAY);
minutes = c.get(Calendar.MINUTE);
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(this,android.R.style.Theme_Holo_Light_Dialog,new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,int minute) {
hours = hourOfDay;
minutes = minute;
string_date = date_time+" "+format(hours) + ":" +format(minutes) ;
addtime.setText(string_date);
Log.e("JEJEJEJE",string_date);
SimpleDateFormat f = new SimpleDateFormat("yyyy/mm/dd HH:mm");
try {
Date d = f.parse(string_date);
milliseconds = d.getTime();
Log.e("LONGGGGGGG", String.valueOf(milliseconds));
} catch (ParseException e) {
e.printStackTrace();
}
}
}, hours, minutes, true);
timePickerDialog.show();
}
I suggest: First, instead of your variables (fields?) year
, month
, day
, hours
and minutes
just declare
private LocalDate date;
private LocalTime time;
private long milliseconds;
(Keep the milliseconds
variable since you will want to have your result here.)
In onDateSet
assign a value to date
in this way:
date = LocalDate.of(selectedYear, selectedMonth + 1, selectedDate);
This is where we are taking into account, as you said, that the date picker’s selectedMonth
is 0-based, while LocalDate
numbers months the way humans do, from 1.
Now your timePicker
method becomes
private void timePicker(){
// Get Current Time
time = LocalTime.now(ZoneId.systemDefault());
// Launch Time Picker Dialog
TimePickerDialog timePickerDialog = new TimePickerDialog(this,
android.R.style.Theme_Holo_Light_Dialog,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,int minute) {
time = LocalTime.of(hourOfDay, minute);
milliseconds = date.atTime(time)
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
Log.e("LONGGGGGGG", String.valueOf(milliseconds));
}
},
time.getHour(),
time.getMinute(),
true);
timePickerDialog.show();
}
You were greatly overcomplicating things. I recommend:
- Don’t use strings for dates or times in your business logic, use date and time objects. This also means you’ve got no need for a formatter like
SimpleDateFormat
(which, I might add, is notoriously troublesome, so it is good that you can do without it). - Use
java.time
, the modern Java date and time API. It is so much nicer to work with than the old-fashioned date and time classes likeCalendar
.
The two points go hand in hand in the above snippets. Also as far as I can see you have no use for the Calendar
object (c
) in setDateField
, just remove it and all use of it.
What went wrong in your code?
The culprit was your SimpleDateFormat
. Try using it like this:
SimpleDateFormat f = new SimpleDateFormat("yyyy/mm/dd HH:mm");
System.out.println(f.parse("2018/04/17 12:45"));
On my computer this prints
Wed Jan 17 12:45:00 CET 2018
It prints a date in January no matter what is in the string. This is because you tried lowercase mm
for month. mm
is for minutes (which you also used correctly), month is uppercase MM
. So your formatter cannot parse a month at all and assigns your date the default month, which is the first month of the year, January. And this date in January was of course also what went into your millesecond value.
Question: Can I use java.time
on Android?
Yes, you can use java.time
on Android. Using it just requires Java 6.
- In Java 8 and later and newer Android versions the new API comes built-in.
- In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310, where the modern API was first described).
- On older Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. Make sure you import the date and time classes from package
org.threeten.bp
and subpackages.
Links
- Oracle tutorial: Date Time, explaining how to use
java.time
. - ThreeTen Backport project
- ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
- Java Specification Request (JSR) 310.
这篇关于如何增加一个月的毫秒数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!