Is there a good way to format a Duration in something like hh:mm:ss, without having to deal with time zones?
I tried this:
DateTime durationDate = Da
Elaborating on other answers, here is an implementation that also formats days:
extension DurationFormatter on Duration {
/// Returns a day, hour, minute, second string representation of this `Duration`.
///
///
/// Returns a string with days, hours, minutes, and seconds in the
/// following format: `dd:HH:MM:SS`. For example,
///
/// var d = new Duration(days:19, hours:22, minutes:33);
/// d.dayHourMinuteSecondFormatted(); // "19:22:33:00"
String dayHourMinuteSecondFormatted() {
this.toString();
return [
this.inDays,
this.inHours.remainder(24),
this.inMinutes.remainder(60),
this.inSeconds.remainder(60)
].map((seg) {
return seg.toString().padLeft(2, '0');
}).join(':');
}
}
Unfortunately the intl
package DateFormat
class does not help: it marks the format of a Duration
as not implemented:
formatDuration(DateTime reference) → String
NOT YET IMPLEMENTED. [...]
Basen on @diegoveloper's answer, I made it an extension which is also extendible
extension DurationExtensions on Duration {
/// Converts the duration into a readable string
/// 05:15
String toHoursMinutes() {
String twoDigitMinutes = _toTwoDigits(this.inMinutes.remainder(60));
return "${_toTwoDigits(this.inHours)}:$twoDigitMinutes";
}
/// Converts the duration into a readable string
/// 05:15:35
String toHoursMinutesSeconds() {
String twoDigitMinutes = _toTwoDigits(this.inMinutes.remainder(60));
String twoDigitSeconds = _toTwoDigits(this.inSeconds.remainder(60));
return "${_toTwoDigits(this.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
String _toTwoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
}
Define this:
extension on Duration {
String format() => '$this'.split('.')[0].padLeft(8, '0');
}
Usage:
String time = Duration(seconds: 3661).format(); // 01:01:01
You can use this:
print('${duration.inHours.toString().padLeft(2, '0')}:
${duration.inMinutes.remainder(60).toString().padLeft(2, '0')}:
${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}');
To do this in a way that is portable, consider the intl
package DateFormat
class: https://pub.dartlang.org/documentation/intl/latest/intl/DateFormat-class.html
Just a quick implementation.
This will display the Duration in [DD]d:[HH]h:[mm]m:[ss]s format, and will ignore the leading element if it was 0. But seconds will always present.
For example:
1d:2h:3m:4s
2h:3m:4s
3m:4s
4s
0s
/// Returns a formatted string for the given Duration [d] to be DD:HH:mm:ss
/// and ignore if 0.
static String formatDuration(Duration d) {
var seconds = d.inSeconds;
final days = seconds~/Duration.secondsPerDay;
seconds -= days*Duration.secondsPerDay;
final hours = seconds~/Duration.secondsPerHour;
seconds -= hours*Duration.secondsPerHour;
final minutes = seconds~/Duration.secondsPerMinute;
seconds -= minutes*Duration.secondsPerMinute;
final List<String> tokens = [];
if (days != 0) {
tokens.add('${days}d');
}
if (tokens.isNotEmpty || hours != 0){
tokens.add('${hours}h');
}
if (tokens.isNotEmpty || minutes != 0) {
tokens.add('${minutes}m');
}
tokens.add('${seconds}s');
return tokens.join(':');
}