问题
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();
}
回答1:
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.
回答2:
Documentation of Calendar object
Calendar
object offers to us method such as getTimeInMillis()
and add(int field, int amount)
. Adding looks like add(Calendar.MONTH, 1)
来源:https://stackoverflow.com/questions/48768874/how-can-i-add-one-month-to-change-into-the-milliseconds