Formatting a Duration like HH:mm:ss - dart

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 = DateTime.fromMillisecondsSinceEpoch(0);
String duration = DateFormat('hh:mm:ss').format(durationDate);
But I always get 1 hour to much, in this case it would say 01:00:00
And When I do this:
Duration(milliseconds: 0).toString();
I get this: 0:00:00.000000

You can use Duration and implement this method:
String _printDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
Usage:
final now = Duration(seconds: 30);
print("${_printDuration(now)}");

You can start creating a format yourself, come on this one:
String sDuration = "${duration.inHours}:${duration.inMinutes.remainder(60)}:${(duration.inSeconds.remainder(60))}";

The shortest, most elegant and reliable way to get HH:mm:ss from a Duration is doing:
format(Duration d) => d.toString().split('.').first.padLeft(8, "0");
Example usage:
main() {
final d1 = Duration(hours: 17, minutes: 3);
final d2 = Duration(hours: 9, minutes: 2, seconds: 26);
final d3 = Duration(milliseconds: 0);
print(format(d1)); // 17:03:00
print(format(d2)); // 09:02:26
print(format(d3)); // 00:00:00
}

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(':');
}

Based 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";
}
}

Here's another version. It's all preference at this point, but I liked that it was dry and didn't need a function declaration (the wrapping function is obviously optional) though it is definately a bit function chaining heavy.
Compact
String formatTime(double time) {
Duration duration = Duration(milliseconds: time.round());
return [duration.inHours, duration.inMinutes, duration.inSeconds].map((seg) => seg.remainder(60).toString().padLeft(2, '0')).join(':');
}
Formatted version
String timeFormatter (double time) {
Duration duration = Duration(milliseconds: time.round());
return [duration.inHours, duration.inMinutes, duration.inSeconds]
.map((seg) => seg.remainder(60).toString().padLeft(2, '0'))
.join(':');
}

Define this:
extension on Duration {
String format() => '$this'.split('.')[0].padLeft(8, '0');
}
Usage:
String time = Duration(seconds: 3661).format(); // 01:01:01

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. [...]

In my opinion the easiest way
String get refactoredDuration{
return Duration(seconds: duration).toString().split('.')[0];
}

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')}');

I prefer thinking of Millisecond as its own unit, rather than as a subunit of something else. In that sense, it will have values of 0-999, so you're going to want to Pad three instead of two like I have seen with other answers. Here is an implementation:
String format(Duration o) {
var mil_s = (o.inMilliseconds % 1000).toString().padLeft(3, '0');
var sec_s = (o.inSeconds % 60).toString().padLeft(2, '0');
return o.inMinutes.toString() + ' m ' + sec_s + ' s ' + mil_s + ' ms';
}
https://api.dart.dev/dart-core/Duration-class.html

You can use this:
Text(RegExp(r'((^0*[1-9]\d*:)?\d{2}:\d{2})\.\d+$')
.firstMatch("$duration") ?.group(1) ?? '$duration'),

String myDuration(Duration duration) {
var date = duration.toString().split(":");
var hrs = date[0];
var mns = date[1];
var sds = date[2].split(".")[0];
return "$hrs:$mns:$sds";
}

Modified the first so when hours are in 00 it will not show.
extension VideoTimer on Duration {
String format() {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final String twoDigitMinutes = twoDigits(inMinutes.remainder(60));
final String twoDigitSeconds = twoDigits(inSeconds.remainder(60));
final hour = twoDigits(inHours);
return "${hour == '00' ? '' : hour + ':'}$twoDigitMinutes:$twoDigitSeconds";
}
}

String _printDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "$twoDigitMinutes:$twoDigitSeconds";
}
Container( //duration of video
child: Text("Total Duration: " + _printDuration(_controller.value.duration).toString()+" Position: " + _printDuration(_controller.value.position).toString()),
),

Related

Flutter/Dart: Split string by first occurrence

Is there a way to split a string by some symbol but only at first occurrence?
Example: date: '2019:04:01' should be split into date and '2019:04:01'
It could also look like this date:'2019:04:01' or this date : '2019:04:01' and should still be split into date and '2019:04:01'
string.split(':');
I tried using the split() method. But it doesn't have a limit attribute or something like that.
You were never going to be able to do all of that, including trimming whitespace, with the split command. You will have to do it yourself. Here's one way:
String s = "date : '2019:04:01'";
int idx = s.indexOf(":");
List parts = [s.substring(0,idx).trim(), s.substring(idx+1).trim()];
You can split the string, skip the first item of the list created and re-join them to a string.
In your case it would be something like:
var str = "date: '2019:04:01'";
var parts = str.split(':');
var prefix = parts[0].trim(); // prefix: "date"
var date = parts.sublist(1).join(':').trim(); // date: "'2019:04:01'"
The trim methods remove any unneccessary whitespaces around the first colon.
Just use the split method on the string. It accepts a delimiter/separator/pattern to split the text by. It returns a list of values separated by the provided delimiter/separator/pattern.
Usage:
const str = 'date: 2019:04:01';
final values = string.split(': '); // Notice the whitespace after colon
Output:
Inspired by python, I've wrote this utility function to support string split with an optionally maximum number of splits. Usage:
split("a=b=c", "="); // ["a", "b", "c"]
split("a=b=c", "=", max: 1); // ["a", "b=c"]
split("",""); // [""] (edge case where separator is empty)
split("a=", "="); // ["a", ""]
split("=", "="); // ["", ""]
split("date: '2019:04:01'", ":", max: 1) // ["date", " '2019:04:01'"] (as asked in question)
Define this function in your code:
List<String> split(String string, String separator, {int max = 0}) {
var result = List<String>();
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
string = string.substring(index + separator.length);
}
return result;
}
Online demo: https://dartpad.dev/e9a5a8a5ff803092c76a26d6721bfaf4
I found that very simple by removing the first item and "join" the rest of the List
String date = "date:'2019:04:01'";
List<String> dateParts = date.split(":");
List<String> wantedParts = [dateParts.removeAt(0),dateParts.join(":")];
Use RegExp
string.split(RegExp(r":\s*(?=')"));
Note the use of a raw string (a string prefixed with r)
\s* matches zero or more whitespace character
(?=') matches ' without including itself
You can use extensions and use this one for separating text for the RichText/TextSpan use cases:
extension StringExtension on String {
List<String> controlledSplit(
String separator, {
int max = 1,
bool includeSeparator = false,
}) {
String string = this;
List<String> result = [];
if (separator.isEmpty) {
result.add(string);
return result;
}
while (true) {
var index = string.indexOf(separator, 0);
print(index);
if (index == -1 || (max > 0 && result.length >= max)) {
result.add(string);
break;
}
result.add(string.substring(0, index));
if (includeSeparator) {
result.add(separator);
}
string = string.substring(index + separator.length);
}
return result;
}
}
Then you can just reference this as a method for any string through that extension:
void main() {
String mainString = 'Here was john and john was here';
print(mainString.controlledSplit('john', max:1, includeSeparator:true));
}
Just convert list to string and search
productModel.tagsList.toString().contains(filterText.toLowerCase())

Delete digits after two decimal point without rounding its value in flutter?

var num1 = 10.12345678
What should i do with num1 to delete digits after two decimal point without rounding its value.
I need output as 10.12
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(
title: ' Delete digits after two decimal point ',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHome(),
));
class MyHome extends StatefulWidget {
#override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
#override
Widget build(BuildContext context) {
var num1 = 10.12345678;
print(num1); // I need output as 10.12
return Container();
}
}
If you want to round the number:
var num1 = 10.12345678;
var num2 = double.parse(num1.toStringAsFixed(2)); // num2 = 10.12
If you do NOT want to round the number:
Create this method:
double getNumber(double input, {int precision = 2}) =>
double.parse('$input'.substring(0, '$input'.indexOf('.') + precision + 1));
Usage:
var input = 113.39999999999999;
var output = getNumber(input, precision: 1); // 113.9
var output = getNumber(input, precision: 2); // 113.99
var output = getNumber(input, precision: 3); // 113.999
You can use intl package (https://pub.dartlang.org/packages/intl#-installing-tab-)
var num1 = 10.12345678;
var f = new NumberFormat("###.0#", "en_US");
print(f.format(num1));
Some answers here did not work (top answer is round, not truncate).
here is a way:
(n * 100).truncateToDouble()/100
if you want round the number use this.
double mod = pow(10.0, places);
return ((val * mod).round().toDouble() / mod);
if you just want to truncate use this.
return val - val % 0.01;
String toFixed2DecimalPlaces(double data, {int decimalPlaces = 2}) {
List<String> values = data.toString().split('.');
if (values.length == 2 && values[0] != '0' && values[1].length >= decimalPlaces && decimalPlaces > 0)
return values[0] + '.' + values[1].substring(0, decimalPlaces);
else
return data.toString();
}
You can also try this ----> (0.2055).toStringAsFixed(2)
var per = 0.2055;
Text( "result view -> ${double.parse((per * 100).toStringAsFixed(2))}%",
style: TextStyle(color: Colors.white, fontSize: 10)),
result value ->
input -> 0.2055
output -> result view ->20.00
There is a simple solution to this problem.
double value = 17.56565656;
//as string
String formatted = value.toStringAsFixed(2); // 17.56
//as double
double formattedDouble = double.parse(formatted); //17.56
extension NoRoundingDecimal on double {
String toDecimalAsFixed(int toDecimal) {
var right;
try {
right = this.toString().split(".")[1].padRight(toDecimal, "0").substring(0, toDecimal);
} catch (e) {
right = "00";
}
var left = this.toString().split(".")[0];
double number = double.parse(left + "." + right);
return number.toStringAsFixed(toDecimal);
}
}
Example1:
double price = 71.999999999;
print("number: ${price.toDecimalAsFixed(3)}");
Result: number: 71.999
Example2:
double price = 71;
print("number: ${price.toDecimalAsFixed(3)}");
Result: number: 71.000

How to remove trailing zeros using Dart

I would like the optimal solution for removing trailing zeros using Dart. If I have a double that is 12.0 it should output 12. If I have a double that is 12.5 it should output 12.5
I made regular expression pattern for that feature.
double num = 12.50; // 12.5
double num2 = 12.0; // 12
double num3 = 1000; // 1000
RegExp regex = RegExp(r'([.]*0)(?!.*\d)');
String s = num.toString().replaceAll(regex, '');
UPDATE
A better approach, just use this method:
String removeDecimalZeroFormat(double n) {
return n.toStringAsFixed(n.truncateToDouble() == n ? 0 : 1);
}
OLD
This meets the requirements:
double x = 12.0;
double y = 12.5;
print(x.toString().replaceAll(RegExp(r'.0'), ''));
print(y.toString().replaceAll(RegExp(r'.0'), ''));
X Output: 12
Y Output: 12.5
Use NumberFormat:
String formatQuantity(double v) {
if (v == null) return '';
NumberFormat formatter = NumberFormat();
formatter.minimumFractionDigits = 0;
formatter.maximumFractionDigits = 2;
return formatter.format(v);
}
If what you want is to convert a double without decimals to an int but keep it as a double if it has decimals, I use this method:
num doubleWithoutDecimalToInt(double val) {
return val % 1 == 0 ? val.toInt() : val;
}
Lots of the answers don't work for numbers with many decimal points and are centered around monetary values.
To remove all trailing zeros regardless of length:
removeTrailingZeros(String n) {
return n.replaceAll(RegExp(r"([.]*0+)(?!.*\d)"), "");
}
Input: 12.00100003000
Output: 12.00100003
If you only want to remove trailing 0's that come after a decimal point, use this instead:
removeTrailingZerosAndNumberfy(String n) {
if(n.contains('.')){
return double.parse(
n.replaceAll(RegExp(r"([.]*0+)(?!.*\d)"), "") //remove all trailing 0's and extra decimals at end if any
);
}
else{
return double.parse(
n
);
}
}
I found another solution, to use num instead of double. In my case I'm parsing String to num:
void main() {
print(num.parse('50.05').toString()); //prints 50.05
print(num.parse('50.0').toString()); //prints 50
}
Here is what I've come up with:
extension DoubleExtensions on double {
String toStringWithoutTrailingZeros() {
if (this == null) return null;
return truncateToDouble() == this ? toInt().toString() : toString();
}
}
void main() {
group('DoubleExtensions', () {
test("toStringWithoutTrailingZeros's result matches the expected value for a given double",
() async {
// Arrange
final _initialAndExpectedValueMap = <double, String>{
0: '0',
35: '35',
-45: '-45',
100.0: '100',
0.19: '0.19',
18.8: '18.8',
0.20: '0.2',
123.32432400: '123.324324',
-23.400: '-23.4',
null: null
};
_initialAndExpectedValueMap.forEach((key, value) {
final initialValue = key;
final expectedValue = value;
// Act
final actualValue = initialValue.toStringWithoutTrailingZeros();
// Assert
expect(actualValue, expectedValue);
});
});
});
}
String removeTrailingZero(String string) {
if (!string.contains('.')) {
return string;
}
string = string.replaceAll(RegExp(r'0*$'), '');
if (string.endsWith('.')) {
string = string.substring(0, string.length - 1);
}
return string;
}
======= testcase below =======
000 -> 000
1230 -> 1230
123.00 -> 123
123.001 -> 123.001
123.00100 -> 123.001
abc000 -> abc000
abc000.0000 -> abc000
abc000.001 -> abc000.001
Here is a very simple way. Using if else I will check if the number equals its integer or it is a fraction and take action accordingly
num x = 24/2; // returns 12.0
num y = 25/2; // returns 12.5
if (x == x.truncate()) {
// it is true in this case so i will do something like
x = x.toInt();
}
To improve on What #John's answer: here is a shorter version.
String formatNumber(double n) {
return n.toStringAsFixed(0) //removes all trailing numbers after the decimal.
}
This function removes all trailing commas. It also makes it possible to specify a maximum number of digits after the comma.
extension ToString on double {
String toStringWithMaxPrecision({int? maxDigits}) {
if (round() == this) {
return round().toString();
} else {
if (maxDigits== null) {
return toString().replaceAll(RegExp(r'([.]*0)(?!.*\d)'), "");
} else {
return toStringAsFixed(maxDigits)
.replaceAll(RegExp(r'([.]*0)(?!.*\d)'), "");
}
}
}
}
//output without maxDigits:
// 1.0 -> 1
// 1.0000 -> 1
// 0.99990 -> 0.9999
// 0.103 -> 0.103
//
////output with maxDigits of 2:
// 1.0 -> 1
// 1.0000 -> 1
// 0.99990 -> 0.99
// 0.103 -> 0.1
user3044484's version with Dart extension:
extension StringRegEx on String {
String removeTrailingZero() {
if (!this.contains('.')) {
return this;
}
String trimmed = this.replaceAll(RegExp(r'0*$'), '');
if (!trimmed.endsWith('.')) {
return trimmed;
}
return trimmed.substring(0, this.length - 1);
}
}
// The syntax is same as toStringAsFixed but this one removes trailing zeros
// 1st toStringAsFixed() is executed to limit the digits to your liking
// 2nd toString() is executed to remove trailing zeros
extension Ex on double {
String toStringAsFixedNoZero(int n) =>
double.parse(this.toStringAsFixed(n)).toString();
}
// It works in all scenarios. Usage
void main() {
double length1 = 25.001;
double length2 = 25.5487000;
double length3 = 25.10000;
double length4 = 25.0000;
double length5 = 0.9;
print('\nlength1= ' + length1.toStringAsFixedNoZero(3));
print('\nlength2= ' + length2.toStringAsFixedNoZero(3));
print('\nlenght3= ' + length3.toStringAsFixedNoZero(3));
print('\nlenght4= ' + length4.toStringAsFixedNoZero(3));
print('\nlenght5= ' + length5.toStringAsFixedNoZero(0));
}
// output:
// length1= 25.001
// length2= 25.549
// lenght3= 25.1
// lenght4= 25
// lenght5= 1
you can do a simple extension on the double class
and add a function which in my case i called it neglectFractionZero()
in this extension function on double(which returns a string) i
split the converted number to string and i check if the split part of the string is "0" , if so i return the first part only of the split and i neglect this zero
you can modify it according to your needs
extension DoubleExtension on double {
String neglectFractionZero() {
return toString().split(".").last == "0"? toString().split(".").first:toString();
}
}
I've came up with improved version of #John.
static String getDisplayPrice(double price) {
price = price.abs();
final str = price.toStringAsFixed(price.truncateToDouble() == price ? 0 : 2);
if (str == '0') return '0';
if (str.endsWith('.0')) return str.substring(0, str.length - 2);
if (str.endsWith('0')) return str.substring(0, str.length -1);
return str;
}
// 10 -> 10
// 10.0 -> 10
// 10.50 -> 10.5
// 10.05 -> 10.05
// 10.000000000005 -> 10
void main() {
double x1 = 12.0;
double x2 = 12.5;
String s1 = x1.toString().trim();
String s2 = x2.toString().trim();
print('s1 is $s1 and s2 is $s2');
}
try trim method https://api.dartlang.org/stable/2.2.0/dart-core/String/trim.html

Converting timestamp

I couldn't find a solution to this, I'm grabbing data from firebase and one of the fields is a timestamp which looks like this -> 1522129071. How to convert it to a date?
Swift example (works) :
func readTimestamp(timestamp: Int) {
let now = Date()
let dateFormatter = DateFormatter()
let date = Date(timeIntervalSince1970: Double(timestamp))
let components = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfMonth])
let diff = Calendar.current.dateComponents(components, from: date, to: now)
var timeText = ""
dateFormatter.locale = .current
dateFormatter.dateFormat = "HH:mm a"
if diff.second! <= 0 || diff.second! > 0 && diff.minute! == 0 || diff.minute! > 0 && diff.hour! == 0 || diff.hour! > 0 && diff.day! == 0 {
timeText = dateFormatter.string(from: date)
}
if diff.day! > 0 && diff.weekOfMonth! == 0 {
timeText = (diff.day == 1) ? "\(diff.day!) DAY AGO" : "\(diff.day!) DAYS AGO"
}
if diff.weekOfMonth! > 0 {
timeText = (diff.weekOfMonth == 1) ? "\(diff.weekOfMonth!) WEEK AGO" : "\(diff.weekOfMonth!) WEEKS AGO"
}
return timeText
}
My attempt at Dart:
String readTimestamp(int timestamp) {
var now = new DateTime.now();
var format = new DateFormat('HH:mm a');
var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp);
var diff = date.difference(now);
var time = '';
if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date); // Doesn't get called when it should be
} else {
time = diff.inDays.toString() + 'DAYS AGO'; // Gets call and it's wrong date
}
return time;
}
And it returns dates/times that are waaaaaaay off.
UPDATE:
String readTimestamp(int timestamp) {
var now = new DateTime.now();
var format = new DateFormat('HH:mm a');
var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000);
var diff = date.difference(now);
var time = '';
if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else {
if (diff.inDays == 1) {
time = diff.inDays.toString() + 'DAY AGO';
} else {
time = diff.inDays.toString() + 'DAYS AGO';
}
}
return time;
}
Your timestamp format is in fact in Seconds (Unix timestamp) as opposed to microseconds. If so the answer is as follows:
Change:
var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp);
to
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
From milliseconds:
var millis = 978296400000;
var dt = DateTime.fromMillisecondsSinceEpoch(millis);
// 12 Hour format:
var d12 = DateFormat('MM/dd/yyyy, hh:mm a').format(dt); // 12/31/2000, 10:00 PM
// 24 Hour format:
var d24 = DateFormat('dd/MM/yyyy, HH:mm').format(dt); // 31/12/2000, 22:00
From Firestore:
Map<String, dynamic> map = docSnapshot.data()!;
DateTime dt = (map['timestamp'] as Timestamp).toDate();
Converting one format to other:
12 Hour to 24 Hour:
var input = DateFormat('MM/dd/yyyy, hh:mm a').parse('12/31/2000, 10:00 PM');
var output = DateFormat('dd/MM/yyyy, HH:mm').format(input); // 31/12/2000, 22:00
24 Hour to 12 Hour:
var input = DateFormat('dd/MM/yyyy, HH:mm').parse('31/12/2000, 22:00');
var output = DateFormat('MM/dd/yyyy, hh:mm a').format(input); // 12/31/2000, 10:00 PM
Use intl package (for formatting)
Full code for anyone who needs it:
String readTimestamp(int timestamp) {
var now = DateTime.now();
var format = DateFormat('HH:mm a');
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var diff = now.difference(date);
var time = '';
if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
time = format.format(date);
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' DAY AGO';
} else {
time = diff.inDays.toString() + ' DAYS AGO';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' WEEK AGO';
} else {
time = (diff.inDays / 7).floor().toString() + ' WEEKS AGO';
}
}
return time;
}
Thank you Alex Haslam for the help!
if anyone come here to convert firebase Timestamp here this will help
Timestamp time;
DateTime.fromMicrosecondsSinceEpoch(time.microsecondsSinceEpoch)
If you are using firestore (and not just storing the timestamp as a string) a date field in a document will return a Timestamp. The Timestamp object contains a toDate() method.
Using timeago you can create a relative time quite simply:
_ago(Timestamp t) {
return timeago.format(t.toDate(), 'en_short');
}
build() {
return Text(_ago(document['mytimestamp'])));
}
Make sure to set _firestore.settings(timestampsInSnapshotsEnabled: true); to return a Timestamp instead of a Date object.
To convert Firestore Timestamp to DateTime object just use .toDate() method.
Example:
Timestamp now = Timestamp.now();
DateTime dateNow = now.toDate();
As you can see in docs
Just make sure to multiply by the right factor:
Micro: multiply by 1000000 (which is 10 power 6)
Milli: multiply by 1000 (which is 10 power 3)
This is what it should look like in Dart:
var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000000);
Or
var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
meh, just use https://github.com/andresaraujo/timeago.dart library; it does all the heavy-lifting for you.
EDIT:
From your question, it seems you wanted relative time conversions, and the timeago library enables you to do this in 1 line of code. Converting Dates isn't something I'd choose to implement myself, as there are a lot of edge cases & it gets fugly quickly, especially if you need to support different locales in the future. More code you write = more you have to test.
import 'package:timeago/timeago.dart' as timeago;
final fifteenAgo = DateTime.now().subtract(new Duration(minutes: 15));
print(timeago.format(fifteenAgo)); // 15 minutes ago
print(timeago.format(fifteenAgo, locale: 'en_short')); // 15m
print(timeago.format(fifteenAgo, locale: 'es'));
// Add a new locale messages
timeago.setLocaleMessages('fr', timeago.FrMessages());
// Override a locale message
timeago.setLocaleMessages('en', CustomMessages());
print(timeago.format(fifteenAgo)); // 15 min ago
print(timeago.format(fifteenAgo, locale: 'fr')); // environ 15 minutes
to convert epochMS to DateTime, just use...
final DateTime timeStamp = DateTime.fromMillisecondsSinceEpoch(1546553448639);
How to implement:
import 'package:intl/intl.dart';
getCustomFormattedDateTime(String givenDateTime, String dateFormat) {
// dateFormat = 'MM/dd/yy';
final DateTime docDateTime = DateTime.parse(givenDateTime);
return DateFormat(dateFormat).format(docDateTime);
}
How to call:
getCustomFormattedDateTime('2021-02-15T18:42:49.608466Z', 'MM/dd/yy');
Result:
02/15/21
Above code solved my problem. I hope, this will also help you. Thanks for asking this question.
I don't know if this will help anyone. The previous messages have helped me so I'm here to suggest a few things:
import 'package:intl/intl.dart';
DateTime convertTimeStampToDateTime(int timeStamp) {
var dateToTimeStamp = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000);
return dateToTimeStamp;
}
String convertTimeStampToHumanDate(int timeStamp) {
var dateToTimeStamp = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000);
return DateFormat('dd/MM/yyyy').format(dateToTimeStamp);
}
String convertTimeStampToHumanHour(int timeStamp) {
var dateToTimeStamp = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000);
return DateFormat('HH:mm').format(dateToTimeStamp);
}
int constructDateAndHourRdvToTimeStamp(DateTime dateTime, TimeOfDay time ) {
final constructDateTimeRdv = dateTimeToTimeStamp(DateTime(dateTime.year, dateTime.month, dateTime.day, time.hour, time.minute)) ;
return constructDateTimeRdv;
}
Assuming the field in timestamp firestore is called timestamp, in dart you could call the toDate() method on the returned map.
// Map from firestore
// Using flutterfire package hence the returned data()
Map<String, dynamic> data = documentSnapshot.data();
DateTime _timestamp = data['timestamp'].toDate();
Simply call this method to return your desired DateTime value in String.
String parseTimeStamp(int value) {
var date = DateTime.fromMillisecondsSinceEpoch(value * 1000);
var d12 = DateFormat('MM-dd-yyyy, hh:mm a').format(date);
return d12;
}
Example: if you pass the TimeStamp value 1636786003, you will get the result as
11-12-2021, 10:46PM
If you are here to just convert Timestamp into DateTime,
Timestamp timestamp = widget.firebaseDocument[timeStampfield];
DateTime date = Timestamp.fromMillisecondsSinceEpoch(
timestamp.millisecondsSinceEpoch).toDate();
I tested this one and it works
// Map from firestore
// Using flutterfire package hence the returned data()
Map<String, dynamic> data = documentSnapshot.data();
DateTime _timestamp = data['timestamp'].toDate();
Test details can be found here: https://www.youtube.com/watch?v=W_X8J7uBPNw&feature=youtu.be
Print DateTime, TimeStamp as string from Firebase Firestore:
Timestamp t;
String s;
DateTime d;
//Declaring Variables
snapshots.data.docs[index]['createdAt'] is Timestamp
? t = snapshots.data.docs[index]['createdAt']
: s =
snapshots.data.docs[index]['createdAt'].toString();
//check createdAt field Timestamp or DateTime
snapshots.data.docs[index]['createdAt'] is Timestamp
? d = t.toDate()
: s =
snapshots.data.docs[index]['createdAt'].toString();
print(s.toString()); //Print Date and Time if DateTime
print(d.toString()); //Print Date and Time if TimeStamp
Recently I've faced the same issue. so I'm using simple logic.
Very simple to Convert TimeStamp to DateTime. We can use this get TimeStamp to DateTime format.
In this example, I'm using Firebase.
import 'package:intl/intl.dart'; /// Import this line
TimeStamp timestamp = database.data()["date"] /// Firebase firestore date field value.
//Example Outputs:- Timestamp(seconds=1657706107, nanoseconds=261000000)
DateTime dateTime = timestamp.toDate(); /// It will be return Date and Time Both.
//Example Outputs:- 2022-07-13 15:25:07.261
String dateOnly = DateFormat('dd/MM/yyyy').format(dateTime); /// It will be only return date DD/MM/YYYY format
//Example Outputs:- 13/07/2022
In a single-line code
import 'package:intl/intl.dart'; /// Import this line
String dateOnly = DateFormat('dd/MM/yyyy').format(database.data()["date"].toDate()); /// It will be only return date DD/MM/YYYY format
//Example Outputs:- 13/07/2022
Thanks for visiting and pushing my reputation 😍
Happy Coding Journey...🤗
2022
Actually the Flutter team updated the Timestamp object.
Now if you want to convert from Timestamp to DateTime you can just use this code:
/*you Timestamp instance*/.toDate()
eg. Timestamp.now().toDate()
Viceversa if you want to convert from DateTime to Timestamp you can do:
Timestamp.fromDate(/*your DateTime instance*/)
eg. Timestamp.fromDate(DateTime.now())
Hope you'll find this helpfull.
All of that above can work but for a quick and easy fix you can use the time_formatter package.
Using this package you can convert the epoch to human-readable time.
String convertTimeStamp(timeStamp){
//Pass the epoch server time and the it will format it for you
String formatted = formatTime(timeStamp).toString();
return formatted;
}
//Then you can display it
Text(convertTimeStamp['createdTimeStamp'])//< 1 second : "Just now" up to < 730 days : "1 year"
Here you can check the format of the output that is going to be displayed: Formats
Timestamp has [toDate] method then you can use it directly as an DateTime.
timestamp.toDate();
// return DateTime object
Also there is an stupid way if you want really convert it:
DateTime.parse(timestamp.toDate().toString())
Long num format date into Calender format from:
var responseDate = 1637996744;
var date = DateTime.fromMillisecondsSinceEpoch(responseDate);
//to format date into different types to display;
// sample format: MM/dd/yyyy : 11/27/2021
var dateFormatted = DateFormat('MM/dd/yyyy').format(date);
// sample format: dd/MM/yyy : 27/11/2021
var dateFormatted = DateFormat('dd/MM/yyyy').format(date);
// sample format: dd/MMM/yyyy : 27/Nov/2021
var dateFormatted = DateFormat('dd/MMM/yyyy').format(date);
// sample format: dd/MMMM/yyyy : 27/November/2021
var dateFormatted = DateFormat('dd/MMMM/yyyy').format(date);
print("Date After Format = $dateFormatted");
Assuming you have a class
class Dtime {
int dt;
Dtime(this.dt);
String formatYMED() {
var date = DateTime.fromMillisecondsSinceEpoch(this.dt);
var formattedDate = DateFormat.yMMMMEEEEd().format(date);
return formattedDate;
}
String formatHMA() {
var time = DateTime.fromMillisecondsSinceEpoch(this.dt * 1000);
final timeFormat = DateFormat('h:mm a', 'en_US').format(time);
return timeFormat;
}
I am a beginner though, I hope that works.
There are different ways this can be achieved based on different scenario, see which of the following code fits your scenario.
Conversion of Firebase timestamp to DateTime:
document['timeStamp'].toDate()
(document["timeStamp"] as Timestamp).toDate()
DateTime.fromMillisecondsSinceEpoch(document['timeStamp'].millisecondsSinceEpoch);
Timestamp.fromMillisecondsSinceEpoch(document['timeStamp'].millisecondsSinceEpoch).toDate();
If timeStamp is in microseconds use:
DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000000);
If timeStamp is in milliseconds use:
DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
Add the following function in your dart file.
String formatTimestamp(Timestamp timestamp) {
var format = new DateFormat('yyyy-MM-dd'); // <- use skeleton here
return format.format(timestamp.toDate());
}
call it as formatTimestamp(document['timestamp'])

splitting date/time field to separate date and time

I have a date/time field (i.e. 2018-04-24 10:00:00) that I want to split into separate date and time. I have the following functions, but it does not work with uib-datepicker since I'm splitting a date/time field like a string:
function returnDate(date) {
var apptDate = date.split(' ')[0];
return apptDate;
}
function returnTime(date) {
var apptTime = date.split(' ')[1].substring(0,5);
var hours24 = parseInt(apptTime.substring(0, 2),10);
var hours = ((hours24 + 11) % 12) + 1;
var amPm = hours24 > 11 ? 'pm' : 'am';
var minutes = apptTime.substring(2);
return hours + minutes + ' ' + amPm;
}
I've also tried to use getDate, getFullYear, getMonth, etc. but I keep getting a TypeError with getDate.
Can someone provide some guidance on this date issue? Thanks!
Because between date and time it has a space, so you can get date and time separately by this way.
Method 1 : Split string
string date_time = "2018-04-24 10:00:00";
string[] words = date_time.Split(' ');//Split string
string date = words[0];//date = 1st object (before space)
string time = words[1];//time= 2nd object (after space)
Method 2 : Using Regular expression
string date_time = "2018-04-24 10:00:00";
string _date = "";
string _time = "";
Regex date = new Regex(#"([0-9-]+)\s");
Match match_date = date.Match(date_time);
Regex time = new Regex(#"\s([0-9:]+)");
Match match_time = time.Match(date_time);
//Date
if (match_date.Success)
{
_date = match_date.Value;
Console.WriteLine(_date);
}
//Time
if (match_time.Success)
{
_time = match_time.Value.Replace(" ","");
Console.WriteLine(_time);
}
have you tried new Date('2018-04-24 10:00:00') and then geting month year etc afterwords from a date object?

Resources