How to sort multiple array based on an array swift? - ios

I would like to sort multiple array based on an array which is array of NSDate
var date = [NSDate]()
var name = [String]()
var job = [String]()
i would like to sort name and job based on the date. Example Like
date = [2016-04-02 01:03:42 +00002,2016-03-02 01:03:42 +0000,2016-05-02 01:03:42 +0000]
name = [john,alex,danson]
job = [engineer,programmer,swimmer]
i would like to sort the date from oldest to the latest then i would like to sort the name and job based on the date . Result Will be Like
date = [2016-03-02 01:03:42 +0000 ,2016-04-02 01:03:42 +0000 , 2016-05-02 01:03:42 +0000 ] //Being Sorted
name = [alex,john,danson]
job = [programmer,engineer,swimmer]
How can i do it ?

extension NSDate {
var day: Int { return NSCalendar.currentCalendar().components(.Day, fromDate: self).day }
}
let result = zip(zip(date, name), jobs).map { ($0.0.0, $0.0.1, $0.1) }.sort { $0.0.day < $1.0.day }
print(result)
This should do it. If you need an explanation, I'll try to explain.
If you want your existing array's to be sorted:
name = name.enumerate().sort { date[$0.index].day < date[$1.index].day }.map { $0.element }
jobs = jobs.enumerate().sort { date[$0.index].day < date[$1.index].day }.map { $0.element }
However, doing this is not safe because if the size of name or jobs is bigger than date, it will crash. You'll have to build some safety inside before using this.
What I forgot to mention is, you could also get the "original" arrays sorted by extracting it from result:
name = result.map { $0.1 }
jobs = result.map { $0.2 }

This is a programming problem instead of Swift problem.
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let dateStrings = ["2016-03-02 01:04:42 +0000","2016-04-02 01:03:42 +0000" , "2016-05-02 01:03:42 +0000" ]
let date = dateStrings.map {
dateString in formatter.dateFromString(dateString)}
let name = ["alex","john","danson"]
let job = ["programmer","engineer","swimmer"]
let combine = date.enumerate().map {
index, date in
return (date!,name[index],job[index])
}
let result = combine.sort{
$0.0.compare($1.0) == NSComparisonResult.OrderedDescending
}

Related

How to find sum for each category in an array?

I have an array that contains multiple items. This is a Realm array. It contains data in the following structure:
Results<Entry> <0x7ff04840e1a0> (
[0] Entry {
name = Salary;
amount = 40000;
date = 2020-03-18 16:00:00 +0000;
category = Main Incomes;
entryType = Income;
},
[1] Entry {
name = Diff;
amount = -500;
date = 2020-04-18 16:00:00 +0000;
category = Misc;
entryType = Expense;
},
[2] Entry {
name = Cat Food;
amount = -399;
date = 2020-04-18 16:00:00 +0000;
category = Animals;
entryType = Expense;
},
[3] Entry {
name = Fish Food;
amount = -599;
date = 2020-04-18 16:00:00 +0000;
category = Animals;
entryType = Expense;
}
)
What I am trying to achieve is to make another array that will 'pivot' totals for each category. So it can work as a pivot table in Excel.
The desired output is an array that will contain totals for each category:
[0] X-Array {
category = Main Incomes;
amount = XXXX;
},
[1] X-Array {
category = Animals;
amount = XXXX;
And so on...
I'm fairly new to this fancy one-liners like .map and .reduce and other Swift's array management sugar, so would very much appreciate the advice!
Thank you!
P.S. I plan to do the same thing with total expenses and incomes in order to calculate closing balance.
I think use Dictionary is easier to do categorize and later you can convert it to array or anything you want
var dict:[String:Double] = [:]
list.forEach {
if let current = dict[$0.category]{
dict[$0.category] = current + $0.amount
}else{
dict[$0.category] = $0.amount
}
}
print(dict)
I think the question is asking how to get the sum for each category, Income, Expense etc. If so, here's how it's done using the .sum function on the results.
let totalIncome = realm.objects(AccountClass.self)
.filter("entryType == 'Income'")
.sum(ofProperty: "amount") as Int
let totalExpense = realm.objects(AccountClass.self)
.filter("entryType == 'Expense'")
.sum(ofProperty: "amount") as Int
print("Total Income: \(totalIncome)")
print("Total Expense: \(totalExpense)")
and the output for your example data is
Total Income: 40000
Total Expense: 1498
If you want a pivot table, you could just add the amounts to an array - if you need the labels, use a tuple to store them in an array like this
let i = ("Income", totalIncome)
let e = ("Expense", totalExpense)
let tupleArray = [i, e]
for account in tupleArray {
print(account.0, account.1)
}
Keep in mind that a Results object is not an array but has some array-like functions. Results are live updating so as the underlying data in Realm changes, the Results change along with it.

Swift Map ARRAYS by Date Array

Im trying to accomplish this: [Swift2 - Sort multiple arrays based on the sorted order of another INT array
But I have to sort by NSDate array.
// dates are actual NSDates, I pasted strings into my sample
var dates:[NSDate] = [2019-12-20 13:00 +0000, 2019-12-20 13:00 +0000, 2019-12-12 13:00 +0000]
var people:[String] = ["Harry", "Jerry", "Hannah"]
var peopleIds:[Int] = [1, 2, 3, 4]
// the following line doesn't work.
// i tried a few variations with enumerated instead of enumerate and sorted instead of sort
// but with now luck
let sortedOrder = dates.enumerate().sort({$0.1>$1.1}).map({$0.0})
dates = sortedOrder.map({points[$0]})
people = sortedOrder.map({people[$0]})
peopleIds = sortedOrder.map({peopleIds[$0]})
Change your dates declaration from NSDate to Date. Date conforms to Comparable protocol since Swift 3.0. Doing so you can simply sort your dates dates.sorted(by: >). To sort your arrays together you can zip your arrays, sort it by dates and map the sorted elements:
let sortedZip = zip(dates, zip(people, peopleIds)).sorted { $0.0 > $1.0}
let sortedPeople = sortedZip.map{ $0.1.0 }
let sortedIDs = sortedZip.map{ $0.1.1 }
If you are trying to sort associated fields you should really consider using an object oriented approach using some kind of model, however, the following should achieve what you are trying to do:
var n = min(dates.count, people.count, peopleIds.count)
var tuples = (0 ..< n).map { (dates[$0], people[$0], peopleIds[$0]) }
.sorted { $0.0 as Date > $1.0 as Date }
dates = tuples.map{ $0.0 }
people = tuples.map{ $0.1 }
peopleIds = tuples.map{ $0.2 }

Swift: Sorting Core Data child entities on fetch based on Date

Introduction
I'm making a calendar app in which I store events using Core Data.
Its composed of: DateKey as the parent (with a one-to-many relationship) to CalendarEventModel. The concept is that DateKey holds a yyyy-dd-MM date string and all events that occur that day are added as a child to that DateKey as CalendarEventModel in a NSOrderedSet. (I'm using Class Definition, none of the entities are abstract.). CalendarEventModel being the entity containing information about one calendar event.
What I try to accomplish
Everything works as intended except that I can't sort my fetched results. When I fetch the DateKeys relevant for the current Calendar I simply can't get them to sort like this:
I want to sort the CalendarEventModel in each DateKey after the CalendarEventModels attribute startDate in ascending order ($0.startDate < $1.startDate). Then have the CalendarEventModels marked isAllDay = false before those with isAllDay = true.
Issue/Question
I've put some clarifications in comment in the code below.
I can't get NSSortDescriptor to work properly ( my attempt is commented in the code below
I've read about NSOrderedSet which the calendarEvents attribute of DateKey is, but I haven't found out how to use it for my sorting criteria.
How would you solve this sorting?
Let me know if more information is needed.
My code
fileprivate func loadEventsFromCoreData() {
dateFormatter.dateFormat = "yyyy dd MM"
let startDate = Date()
var predicatesForFetch : [NSPredicate] = []
var dateStringArray : [String] = []
var fetchResultsArray : [DateKey]?
for num in 0...9 {
let newDate = startDate.add(TimeChunk(seconds: 0, minutes: 0, hours: 0, days: num, weeks: 0, months: 0, years: 0))
let datePredicate = dateFormatter.string(from: newDate)
dateStringArray.append(datePredicate)
predicatesForFetch.append(NSPredicate(format: "dateInfo == %#", datePredicate))
}
setupSectionArray(eventArray: dateStringArray)
// I'm getting the correct DateKeys and their events.
let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForFetch)
let eventFetch : NSFetchRequest<DateKey> = DateKey.fetchRequest()
eventFetch.predicate = compoundPredicate
// I've tried specifying this sortDescriptor and added it to the eventFetch:
// let descriptor = NSSortDescriptor(key: "calendarEvents", ascending: true) { ($0 as! CalendarEventModel).startDate!.compare(($1 as! CalendarEventModel).startDate!) }
// let sortDescriptors = [descriptor]
// eventFetch.sortDescriptors = sortDescriptors
do {
fetchResultsArray = try coreDataContext.fetch(eventFetch)
} catch {
print("Core Data initial fetch failed in Calendar Controller: \(error)")
}
guard fetchResultsArray != nil else { return }
// Xcode doesn't recognize the .sort() function which does not have a return value... and I don't think its a good idea to use the return function at all since I will have to delete all children and re add the sorted for each fetch.
for eventArray in fetchResultsArray! {
eventArray.calendarEvents?.sorted(by: { ($0 as! CalendarEventModel).startDate!.compare(($1 as! CalendarEventModel).startDate!) == .orderedAscending })
eventArray.calendarEvents?.sorted { ($0 as! CalendarEventModel).isAllDay && !($1 as! CalendarEventModel).isAllDay }
}
events = fetchResultsArray!
}
Thanks for reading my question.
Some notes:
Basically you cannot sort dates in string format "yyyy dd MM", either use "yyyy MM dd" or – highly recommended – Date type.
You cannot sort a relationship in place. To-many relationships are Sets which are unordered. By the way declare the relationship as native Set<CalendarEventModel> rather than unspecified NSSet and as non-optional.
Don't use a compound predicate, use one predicate and don't fetch DateKey records, fetch CalendarEventModel records with predicate dateKey.dateInfo >= startDate && dateKey.dateInfo <= endDate and add there the two sort descriptors.
Fetching filtered and sorted records once is much more efficient than get the relationship items and sort them manually.
Edit:
To get midnight of today and + 9 days use
let calendar = Calendar.current
let now = Date()
let nowPlus9Days = calendar.date(byAdding: .day, value: 9, to: now)!
let startDate = calendar.startOfDay(for: now)
let endDate = calendar.startOfDay(for: nowPlus9Days)
This code fetches all sorted CalendarEventModel in the date range and groups the array to a [Date : [CalendarEventModel]] dictionary
let predicate = NSPredicate(format: "dateKey.dateInfo >= %# && dateKey.dateInfo <= %#", startDate as CVarArg, endDate as CVarArg)
let sortDescriptors = [NSSortDescriptor(key: "startDate", ascending: true), NSSortDescriptor(key: "isAllDay", ascending: true)]
let eventFetch : NSFetchRequest<CalendarEventModel> = CalendarEventModel.fetchRequest()
eventFetch.predicate = predicate
eventFetch.sortDescriptors = sortDescriptors
do {
let fetchResultsArray = try coreDataContext.fetch(eventFetch)
let groupedDictionary = Dictionary(grouping: fetchResultsArray, by: {$0.startDate})
} catch {
print("Core Data initial fetch failed in Calendar Controller: \(error)")
}
Don't execute good code after the catch block. Put all good code in the do scope after the fetch.

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'])

Sort value in dictionary that resides within an array

I have an Array: var messageArray = [AnyObject]() and in that Array there is a single tuple that contains Dictionaries with 10 key/value paires (9 of them not important for the sort): var messageDetailDict = [String: AnyObject]()
Getting and setting those values all work correctly, however now I want to sort the Array by 1 of the values (not keys) of the Dictionary.
Example -> The Array has a tuple containing several Dictionaries:
The key in the Dictionary (which is the first element in the Array) is: 'ReceivedAt' which has a value of 21-03-2015
The key in the Dictionary (which is the second element in the Array) is: 'ReceivedAt' which has a value of 20-03-2015
The key in the Dictionary (which is the third element in the Array) is: 'ReceivedAt' which has a value of 15-03-2015
Now the Array should be sorted so that the values of 'ReceivedAt' will be sorted from earliest date, to the last date.
Hope this makes sense, but it's a bit difficult to explain. Thanks!
EDIT >>>>>
This is the println(messageArray) output:
[(
{
ConversationId = "94cc96b5-d063-41a0-ae03-6d1a868836fb";
Data = "Hello World";
Id = "eeb5ac08-209f-4ef0-894a-72e77f01b80b";
NeedsPush = 0;
ReceivedAt = "/Date(1439920899537)/";
SendAt = "/Date(1436620515000)/";
Status = 0;
},
{
ConversationId = "94cc96b5-d063-41a0-ae03-6d1a868836fb";
Data = "Hello World";
Id = "86b8766d-e4b2-4ef6-9112-ba9193048d9d";
NeedsPush = 0;
ReceivedAt = "/Date(1439921562909)/";
SendAt = "/Date(1436620515000)/";
Status = 0;
}
)]
And the received date is converted to a string with the following method (I do think however this is not important, as it is a time interval, and therefore OK to sort):
func getTimeStampFromAPIValue(dateTimeReceived: String) -> String {
let newStartIndex = advance(dateTimeReceived.startIndex, 6)
let newEndIndex = advance(dateTimeReceived.endIndex, -2)
let substring = dateTimeReceived.substringWithRange(newStartIndex..<newEndIndex) // ell
let receivedAtValueInInteger = (substring as NSString).doubleValue
let receivedAtValueInDate = NSDate(timeIntervalSince1970:receivedAtValueInInteger/1000)
//format date
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yy hh:mm"
var dateString = dateFormatter.stringFromDate(receivedAtValueInDate)
return dateString
}
Since the values of ReceivedAt are timestamps as strings you could apply the following algorithm:
var sortedArray = messageArray.sorted { (dict1, dict2) in
// Get the ReceivedAt value as strings
if let date1String = dict1["ReceivedAt"] as? String,
let date2String = dict2["ReceivedAt"] as? String {
// Compare the date strings to find the earlier of the two
return date1String.compare(date2String) == .OrderedAscending
}
// Couldn't parse the date, make an assumption about the order
return true
}
Try this, change OrderedAscending with OrderedDescending if need in inverse order
messageArray.sortInPlace {
($0["ReceivedAt"] as! NSDate).compare($1["ReceivedAt"] as! NSDate) == .OrderedAscending
}

Resources