Dart - 如何设置 DateTime 对象的小时和分钟

47

如何设置/更改DateTime对象的小时和/或分钟。类似于JavaScript中的Date.setHours(..)

例如,如果我执行了以下操作:

var time = DateTime.parse("2018-08-16T11:00:00.000Z");

如何设置time的小时和分钟?

10个回答

81
var newHour = 5;
time = time.toLocal();
time = new DateTime(time.year, time.month, time.day, newHour, time.minute, time.second, time.millisecond, time.microsecond);

已经讨论过增加一个update()方法来仅修改特定部分,但似乎尚未实现。


1
谢谢,但这正是我已经在做的。我正在寻找更高效的方法。 - Kingsley CA
有一些工作正在进行中,但它还没有被纳入 SDK https://github.com/dart-lang/sdk/pull/24646。如果您经常需要这样的功能,可以自己创建一个便捷函数来使事情更容易。 - Günter Zöchbauer
3
改变日期的另一种方法是 time.add(Duration(hours: 2, minutes: 30)),但我怀疑它是否是一个解决方案。我不知道其他改变 DateTime 的方法。 - Andrii Turkovskyi
@AndreyTurkovsky 这要看你想要做什么。当穿越夏令时边界时,添加/删除时间间隔可能会产生令人惊讶的效果。 - Günter Zöchbauer

41

现在通过扩展,你可以像这样做:

extension MyDateUtils on DateTime {
  DateTime copyWith({
    int? year,
    int? month,
    int? day,
    int? hour,
    int? minute,
    int? second,
    int? millisecond,
    int? microsecond,
  }) {
    return DateTime(
      year ?? this.year,
      month ?? this.month,
      day ?? this.day,
      hour ?? this.hour,
      minute ?? this.minute,
      second ?? this.second,
      millisecond ?? this.millisecond,
      microsecond ?? this.microsecond,
    );
  }
}

如何使用此变量? - dontknowhy
2
最终,使用 copyWith 方法来复制旧值并更改字段:final newVariable = oldValue.copyWith(year: oldValue.year+1); - A. Tratseuski
以上示例是正确的,但不支持空安全,请确保在每个变量类型后添加“?”。例如:int? year - user7209975
是的,我应该更新它。 - A. Tratseuski

12
从Dart 2.19.0开始,copyWith方法被添加到DateTime中,可以像这样使用:
final currentTime = DateTime.now();
final twelve = currentTime.copyWith(hour: 12, minute: 0);

12

我有一个更简单的解决方案:

DateTime newDate = DateTime.now();
DateTime formatedDate = newDate.subtract(Duration(hours: newDate.hour, minutes: newDate.minute, seconds: newDate.second, milliseconds: newDate.millisecond, microseconds: newDate.microsecond));

那么来自 'formatedDate' 的 XX:XX 应该是 00:00

解释:

formatedDate 是一个新的 DateTime 变量,其内容是从 newDate 中减去小时、分钟等得到的。


3
你可以使用Dart中的扩展方法来扩展现有库。
首先,通过扩展DateTime对象来定义你的扩展方法:
extension DateTimeExt on DateTime {
  DateTime applyTimeOfDay({required int hour, required int minute}) {
      return DateTime(year, month, day, hour, minute);
}
}

一旦你定义了新的方法,你就可以像调用该对象已定义的方法一样调用它。
例如,在这种情况下,一旦你定义了 applyTimeOfDay() 方法,你可以这样调用它:
int myNewHour = 10
int myNewMinute = 8
var time = DateTime.parse("2018-08-16T11:00:00.000Z");
time = time.applyTimeOfDay(hour : myNewHour, minute : myNewMinute);

2

您可以删除当前的小时和分钟,然后添加您想要的小时和分钟。

因此,如果您想将时间设置为例如23:59,您可以这样做:

    final date = DateTime.now();
    date
      ..subtract(Duration(hours: date.hour, minutes: date.minute))
      ..add(Duration(hours: 23, minutes: 59));

(请注意,其他时间单位如秒和毫秒在此处未更改)

2

我认为这是比被接受的答案更好的解决方案:

DateTime dateTime = DateFormat('dd-MM-yyyy h:mm:ssa', 'en_US').parseLoose('01-11-2020 2:00:00AM');

5
为什么涉及分析的方法更好? - nipunasudha

0

在使用 DateTime 对象的格式化表单(使用 DateFormat)时,我遇到了一些问题,因为 showDatePicker 会带来一个新的 DateTime 实例,并且调用 setState 对视图没有影响。

可能有更好的方法来解决我的问题,但我决定创建自己的方法,可以使用 .update 方法进行更新。

import 'package:flutter/material.dart';

class MDateTime {
  int year, month, day, hour, min, sec;

  factory MDateTime.fromDateTime(DateTime dateTime) {
    return MDateTime(
      dateTime.year,
      dateTime.month,
      dateTime.day,
      dateTime.hour,
      dateTime.minute,
      dateTime.second,
    );
  }

  MDateTime([
    this.year = 0,
    this.month = 0,
    this.day = 0,
    this.hour = 0,
    this.min = 0,
    this.sec = 0,
  ]);

  void update({
    int? newYear,
    int? newMonth,
    int? newDay,
    int? newHour,
    int? newMin,
    int? newSec,
  }) {
    year = newYear ?? year;
    month = newMonth ?? month;
    day = newDay ?? day;
    hour = newHour ?? hour;
    min = newMin ?? min;
    sec = newSec ?? sec;
  }

  DateTime toDateTime() {
    return DateTime(year, month, day, hour, min, sec);
  }

  TimeOfDay toTimeOfDay() {
    return TimeOfDay(hour :hour, minute:  min);
  }

  String formatDate({String divider = "-"}){
    return "$year$divider$month$divider$day";
  }

  String formatTime({String divider = ":"}){
    return "$hour$divider$min$divider$sec";
  }
}

此外,无需使用其他包来进行日期时间格式化。

0
你也可以通过在DateTime上加减来实现这一点,使用这个包Jiffy。它还会考虑闰年和每个月的天数。
var updateTime = Jiffy.parse("2018-08-16T11:00:00.000Z").add(hours: 1); // 2018-08-16 12:00:00.000Z

print(updateTime.dateTime); // 2018-08-16 12:30:00.000Z

// also you can format it
print(updateTime.format("yyyy, MMM")); // 2018, Aug

// or use default formats
print(updateTime.yMMMEdjm); // Thu, Aug 16, 2018 12:30 PM

我们可以使用这个包来四舍五入时间吗? - omer

-1

var newHour = 5; time = time.toLocal(); time = new DateTime(time.year, time.month, time.day, newHour, time.minute, time.second, time.millisecond, time.microsecond);


目前你的回答不够清晰,请[编辑]以添加更多细节,帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接