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'])
I am currently building an Instagram clone.
I am quit new so please forgive me if this question is answered easily.
I just want to have a specific score attached to each post.
I already managed to give each new post a score 0f 0 to start with and each time its liked it increases by 100, disliked it decreases by 100.
for every comment it grows by 50 points.
Because I want to order them smartly and want it to show different posts at the top over time I wanted to include a third variable which influences the score.
I want it to decrease the score by -10 each hour since its been uploaded.
The increase and decrease is done in my function incrementLikes() /incrementComments() .
I know that I can't modify the value of score for the time since its uploaded there, but I don't know where else.
My date extension (prob where I can do it?)
extension Date {
func timeAgoDisplay() -> String {
let secondsAgo = Int(Date().timeIntervalSince(self))
let minute = 60
let hour = 60 * minute
let day = hour * 24
let week = day * 7
let month = week * 4
let quotient : Int
let unit: String
if secondsAgo < minute {
quotient = secondsAgo
unit = "Sekunde"
} else if secondsAgo < hour {
quotient = secondsAgo / minute
unit = "Minute"
} else if secondsAgo < day {
quotient = secondsAgo / hour
unit = "Stunde"
} else if secondsAgo < week {
quotient = secondsAgo / day
unit = "Tage"
} else if secondsAgo < month {
quotient = secondsAgo / week
unit = "Woche"
} else {
quotient = secondsAgo / month
unit = "Monat"
}
return "Vor \(quotient) \(unit)\(quotient == 1 ? "" : "n")"
}
}
my function in homeTableViewCell where I set the date
func updateView() {
captionLabel.userHandleLinkTapHandler = { label,string, range in
let mention = String(string.characters.dropFirst())
API.User.observeUserByUsername(username: mention.lowercased(), completion: { (user) in
self.delegate?.goToProfileUserViewController(userId: user.id!)
})
}
guard let count = post?.commentCount else {return}
if count == 0 {
commentButton.setTitle("Schreibe den ersten Kommentar", for: UIControlState.normal)
}else if count == 1 {
commentButton.setTitle("Sieh dir den ersten Kommentar an", for: UIControlState.normal)
} else {
commentButton.setTitle("Alle \(count) Kommentare ansehen", for: UIControlState.normal)
}
let timeAgoDisplay = post?.creationDate?.timeAgoDisplay()
timeLabel.text = timeAgoDisplay
}
thanks for your help :)
The idea of updating the score every hour using a time is based on the idea that the app is constantly running, which seems flawed.
You could instead have something like
var score: Int {
return likes*100 - dislikes*100 + comments*50 - hoursSinceUpload()*10
}
where hoursSinceUpload is computed by something like (see Getting the difference between two NSDates in (months/days/hours/minutes/seconds) for reference)
func hoursSinceUpload() -> Int {
return Calendar.current.dateComponents([.hour], from: uploadDate, to: Date()).hour
}
I have an app that I'm building in Swift that needs to determine if a store/restaurant is currently open. It queries a database that I have control of, so I can set the open hours however I'd like. Currently I have an openTime/closeTime column for each day of the week set as a timestamp. For example: MonOpen = 11:00, MonClose = 19:00.
How can I use swift to determine if the place of business is currently open? I'm imagining something like if currentTime > MonOpen & currentTime < MonClose {...
An example of this is the iOS Starbucks app. If you go to locations, each location is listed with an "Open until 22:00" or "Open until 23:00."
It's just a matter of playing with the timezone, whether you use the user system's timezone or let them choose another one in the app's settings:
let tz = NSTimeZone.defaultTimeZone()
let now = NSCalendar.currentCalendar().componentsInTimeZone(tz, fromDate: NSDate())
if now.weekDay == 2 && now.hour > MonOpen && now.hour < MonClose {
// The store is open
}
I would like to take another crack at this question since we now have Swift 5.1 and most businesses have more complex opening times than just in hours.
import Foundation
// There might be an enum in Swift
// that I did not bother to lookup
enum Days : Int {
case Sun = 1
case Mon = 2
case Tue = 3
case Wed = 4
case Thu = 5
case Fri = 6
case Sat = 7
}
func isOfficeOpenNow(weekSchedule: [Days: (Int, Int)]) -> Bool {
let tz = NSTimeZone.default
let now = NSCalendar.current.dateComponents(in: tz, from: Date())
guard let weekday = now.weekday,
let today = Days(rawValue: weekday),
let hour = now.hour,
let minute = now.minute else {
return false
}
guard let todayTuple = weekSchedule[today] else {
return false // no key, means closed
}
let opensAt = todayTuple.0
let closesAt = todayTuple.1
assert(opensAt < closesAt, "Your schedule is setup wrong.")
let rightNowInMinutes = hour * 60 + minute
return rightNowInMinutes > opensAt &&
rightNowInMinutes < closesAt
}
To use this just define a dictionary for each day.
Key is the dayofweek. Could have used a string "Mon","Tue",etc
but then you will need a mapping or DateFormatter
Value is a tuple (int, int) for (open, close) in minutes
Using minutes, as many stores have more complex open
closing times than just hours
let schedule = [
Days.Mon: (9*60+30, 22*60+30),
Days.Tue: (9*60+30, 23*60+05),
Days.Wed: (9*60+30, 22*60+30),
Days.Thu: (9*60+30, 22*60+30),
Days.Fri: (9*60+30, 22*60+30),
]
if isOfficeOpenNow(weekSchedule: schedule) {
print("Store open")
} else {
print("Store closed")
}
If a specific week is a holiday, just update the schedule for the week and all is good with the world.
If a day is closed, just remove the key from the schedule.
I have received duration from service. the duration is 0.73
so i have tried this
if (value >= 1.0 && value < 60.0) {
double value = 0.73;
double d = value * 1000;
NSLog(#"milli seconds = %03d ms",(int)d);
//Output is 730ms --> which is correct.
}
If i received 1.45 above 1.0
double value = 1.45
if (value >= 1.0 && value < 60.0) {
double d = value * 1000;
double sec = (int)value % 60;
NSLog(#"%02d s:%012.f ms",(int)sec, d);
//Output is 01 s: 000000001450 ms
}
The output should be as 01s:450ms
I need to change this to 01s:450ms. but i cant try this. any body help this. Thanks in Advance.
%012.f means that you want your answer to always have 12 places with 0 padding for those places. To change it to what you have written you can do
NSLog(#"%02ds:%03.0f ms",(int)sec, d);
This will print the milliseconds number with no decimal places so if you have 1.4566 you will end up with 01s:457ms. Is this what you were after?
You can find out loads more about string formatting by looking up the man page for printf on a *nix machine go to terminal and type man printf.
try this code
double value = 1.45;
if (value >= 1.0 && value < 60.0) {
int sec = (int)value;
int minisecond = value*1000 - sec*1000;
NSLog(#"%02d s:%3d ms",(int)sec, minisecond);
//Output is 01 s:450 ms
}
I know the question is answered. But people who are curious to use NSDateComponentsFormatter
class customFormatter: NSDateComponentsFormatter {
override init() {
super.init()
}
convenience required init(coder aDecoder: NSCoder) {
self.init()
}
override func stringForObjectValue(obj: AnyObject) -> String? {
if(obj.isKindOfClass(NSNumber.classForCoder()))
{
var whole = UnsafeMutablePointer<Float>.alloc(obj.integerValue)
var fractional : Float
fractional = modff(obj.floatValue, whole)
return "\( obj.floatValue - fractional )s \(fractional * 1000)ms"
}
return "Bad Input Type"
}
}
let formatter = customFormatter()
formatter.unitsStyle = .Abbreviated
let number = 10.4
let string = formatter.stringForObjectValue(number)
double value = 1.45;
if (value >= 1.0 && value < 60.0) {
double sec = (int)value % 60;
double d = (value - sec) * 1000;
NSLog(#"%02ds:%.0f ms",(int)sec, d);
}