我怎样才能把一个月加到毫秒呢?

How can I add one month to change into the milliseconds?

我在将当前时间更改为毫秒时遇到问题,显示的毫秒数比设置的日期和时间早一个月。我知道计算机从 0 开始月份,我该如何解决这个问题?首先,我将日期和时间转换为String,然后将String转换为SimpleDateFormat中的日期,然后将日期转换为Long。[=15] =]

例如:当用户输入日期“2018/2/14 11:18”(上午),日期转换为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();

}

Documentation of Calendar object

Calendar对象为我们提供了getTimeInMillis()add(int field, int amount)等方法。添加看起来像 add(Calendar.MONTH, 1)

我建议:首先,不要使用变量(字段?)yearmonthdayhoursminutes 只需声明

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();

}

你把事情复杂化了。我推荐:

  1. 不要在业务逻辑中使用日期或时间字符串,使用日期和时间对象。这也意味着您不需要像 SimpleDateFormat 这样的格式化程序(我可能会补充说,这是出了名的麻烦,所以最好不要它)。
  2. 使用 java.time,现代 Java 日期和时间 API。它比 old-fashioned 日期和时间 类 如 Calendar.
  3. 更好用

这两点在上面的片段中是齐头并进的。另外,据我所知,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 出现 built-in.
  • 在 Java 6 和 7 中获取现代 类 的 ThreeTen Backport(ThreeTen for JSR 310,现代 API 首次被描述)。
  • 在较早的 Android 上,使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。确保从包 org.threeten.bp 和子包中导入日期和时间 类。

链接