I get from API a json object with datetime field in format:
"date": "6/23/2018 12:00:00 AM",
How to transform it to valid date time object in Dart?
While parsing it I get an error
Invalid date format
class User {
int id;
DateTime date;
User({this.id,this.date});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
date: DateTime.parse(json['date'])
);
}
}
final dateRegExp =
RegExp(r'(\d{1,2})/(\d{1,2})/(\d{4}) (\d{2}):(\d{2}):(\d{2}) (AM|PM)');
var match = dateRegExp.firstMatch('6/23/2018 12:00:00 AM');
var result = DateTime(
int.parse(match[3]),
int.parse(match[1]),
int.parse(match[2]),
int.parse(match[4]) + (match[7] == 'AM' ? 0 : 12),
int.parse(match[5]),
int.parse(match[6]),
);
print(result);
You can do this in a simpler way by using this package, Jiffy. It tries to mimic the simplicity of momentjs
To get the DateTime object
DateTime d = Jiffy("6/23/2018 12:00:00 AM", "MM/dd/yyyy hh:mm:ss a").dateTime;
You can also format it
Jiffy("6/23/2018 12:00:00 AM", "MM/dd/yyyy hh:mm:ss a").format("yyyy, MM dd"); // 2018, 06 23
// You can also use default formats
Jiffy("6/23/2018 12:00:00 AM", "MM/dd/yyyy hh:mm:ss a").yMMMEdjm; // Sat, Jun 23, 2018 12:00 AM
Related
This question already has an answer here:
How to format DateFormatter(NSDateFormattter) for Date String
(1 answer)
Closed 5 years ago.
I having a date string:
Wed Mar 25 2017 05:30:00 GMT+0530 (IST)
I want to convert this string to the Date object in Swift 3.
I have referred to Link1, Link 2 and Link 3 for generating the format for this date string but could not get the correct format.
1) If you have string which contains timezone names like IST or GMT differences, then you can use NSDateDetector as explained in this SO post answer:
extension String {
var nsString: NSString { return self as NSString }
var length: Int { return nsString.length }
var nsRange: NSRange { return NSRange(location: 0, length: length) }
var detectDates: [Date]? {
return try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
.matches(in: self, range: nsRange)
.flatMap{$0.date}
}
}
//your example here
let dateString = "Wed Mar 25 2017 05:30:00 GMT+0530 (IST)"
if let dateDetected = dateString.detectDates?.first {
let date = dateDetected//Mar 25, 2017, 5:30 AM
print(dateDetected)//2017-03-25 00:00:00 +0000 - this is GMT time
}
Mar 25, 2017, 5:30 AM //date converted to local time zone
2017-03-25 00:00:00 +0000 //printed value of GMT time
2) Or if you some how able to remove GMT and IST reference from your string then try this:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, MMM d yyyy HH:mm:ss Z"
let date = dateFormatter.date(from: "Wed Mar 25 2017 05:30:00 +0530")!
print(date)
It will give you
Mar 25, 2017, 5:30 AM //date converted to local time zone
2017-03-25 00:00:00 +0000 //printed value of GMT time
var dateString = "Wed, 25 Mar 2017 05:30:00 +0000"
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss Z"
var dateFromString = dateFormatter.date(from: dateString)
print(dateFromString)
I'm getting a string representation of a date from a json that looks like the following:
let dateString = "2016-12-31T00:10:00+01:00"
In order to model it as a Date object I'm using a date formatter like so:
let dateForm = DateFormatter()
dateForm.locale = Locale(identifier: "fr_FR")
dateForm.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateForm.timeZone = TimeZone.current
When I turn it into a Date, my Playground output is correct:
let date = dateForm.date(from: dateString)
=> Output: "Dec 31, 2016, 12:10 AM"
But if I try to print this exact same object (date) I get the following output:
print(date!)
=> Output: "2016-12-30 23:10:00 +0000\n"
My question is: How can I be sure that I'm dealing with the correct date (by correct I mean with my local time zone (GMT+01)) ?
When you print the date output 2016-12-30 23:10:00 +0000 and your GMT is +00:00
but when you get the string from date it will return string as per your given format And your Locale (fr_FR) output 2016-12-31T00:10:00+01:00 and your GMT is +01:00
if you want to date from string then
date output = your string date - (your GMT)
In your case
2016-12-30 23:10:00 = 2016-12-31 00:10:00 - (+01:00)
i am trying to calculate the time between two dates. One of the dates is today and the other date is somewhere in the future.
The issue is the date in future is separated into two string, the first containing the date and the other containing the time for that date. When i put the two strings together to a single string and try to convert it to a NSDate i get Nil.
I assume there is something wrong with my date variable.
let eventDate: String? = "21 Aug Sun 2016"
let eventTime: String? = "9:00 PM"
let date : String? = "\(eventDate!) \(eventTime!)"
print(date!) // "21 Aug Sun 2016 9:00 PM"
let formatter = NSDateFormatter()
formatter.dateFormat = "dd MMM eee yyyy HH:MM a"
formatter.AMSymbol = "AM"
formatter.PMSymbol = "PM"
if let dateTimeForEvent = formatter.dateFromString(date!) {
print(dateTimeForEvent)
}else {
print("Error")// prints error
}
Two things:
You have the wrong format for the time. It should be h:mm a. HH is for a two-digit, 24-hour hour. You have a 1 or 2 digit, 12-hour hour. And MM is for a 2-digit month. Use mm for a two-digit minute.
If your date and time strings will always be in English, you need to set the formatter's locale to an English locale. If you don't, your code will always return a nil date on any device using a language other than English.
Your primary issue is that you're using HH, which is for 24-hour time, instead of hh, and MM (which is for month) instead of mm. Try this:
import Foundation
let eventDate = "21 Aug Sun 2016"
let eventTime = "9:00 PM"
let eventDateTime = "\(eventDate) \(eventTime)"
print(eventDateTime) // "21 Aug Sun 2016 9:00 PM"
let formatter = NSDateFormatter()
formatter.dateFormat = "dd MMM eee yyyy hh:mm a"
if let date = formatter.dateFromString(eventDateTime) {
print(date) // 2016-08-21 21:00:00 +0000
}
else {
print("Error")// prints error, no shit? why is this comment here?
}
Side notes:
Why is a variable called date, if it's a String??
Why is date an optional, anyway? You assigned it a literal value.
You don't have to set the AMSymbol and the PMSymbol. Those only pertain to printing dates, not parsing them.
I'm not understanding exactly why it's not sorting properly. I have an NSDictionary that contains key values of times in the day. When I try to sort it, it's not properly ordered.
events = #{#"12:00 PM" : #[#"1"],
#"12:30 PM" : #[#"2"],
#"1:00 PM" : #[#"3", #"4"],
#"1:30 PM" : #[#"5", #"11"],
#"2:00 PM" : #[#"6"],
#"3:00 PM" : #[#"7"],
#"3:30 PM" : #[#"8"],
#"4:00 PM" : #[#"9"],
#"4:30 PM" : #[#"10", #"11"],
#"5:00 PM" : #[#"12", #"13", #"14"]};
eventTimes = [ [events allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
When I NSLog eventTimes, it produces the output:
(
"1:00 PM",
"1:30 PM",
"12:00 PM",
"12:30 PM",
"2:00 PM",
"3:00 PM",
"3:30 PM",
"4:00 PM",
"4:30 PM",
"5:00 PM" )
How can I achieve this output?
(
"12:00 PM",
"12:30 PM",
"1:00 PM",
"1:30 PM",
"2:00 PM",
"3:00 PM",
"3:30 PM",
"4:00 PM",
"4:30 PM",
"5:00 PM" )
UPDATE: I tried:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"] ];
[formatter setDateFormat:#"HH:mm"];
NSString *etaStr = [eventTimes objectAtIndex:section];
NSDate *generatedDate = [formatter dateFromString:etaStr];
NSLog(#"%#", [formatter stringFromDate:generatedDate]);
However, I get nil.
Keep time as number of seconds, timestamp or NSDate.
Use regular sort.
Use NSDateFormatter to produce time string in preferred format. Generally keep your application data in format that is friendly to your internal data organization and do formatting before you display it on screen.
Regarding NSDateFormatter questions and how to convert time string to NSDate, I played around in Playground and it seems that the key is to set ShortStyle format for time, setup en_US locale since you convert from 12h time and make sure you use UTC timezone to avoid any time offset because your time is absolute anyway.
// Playground - noun: a place where people can play
import UIKit
// Input
var times = [
"3:30 PM", "4:00 PM", "4:30 PM",
"5:00 PM", "12:30 PM", "12:00 PM",
"1:00 PM", "1:30 PM", "2:00 PM",
"3:00 PM"
]
// Create array of NSDate objects
var dates = NSMutableArray()
println("Convert time string to NSDate")
println()
// Setup formatter for the US time style
let formatter = NSDateFormatter()
formatter.dateFormat = "h:mm a"
formatter.dateStyle = NSDateFormatterStyle.NoStyle
formatter.timeStyle = NSDateFormatterStyle.ShortStyle
formatter.timeZone = NSTimeZone(name: "UTC")
formatter.locale = NSLocale(localeIdentifier: "en_US")
// Loop thru input data and convert time string to NSDate
for t in times {
let date = formatter.dateFromString(t)
dates.addObject(date!)
println("t = \(t) converted as \(date)")
}
println()
println("Sort array of NSDate objects")
println()
// Sort dates
let sortedDates = dates.sortedArrayUsingDescriptors([ NSSortDescriptor(key: "self", ascending: true) ])
// Print out sorted array of dates
for d in sortedDates {
let date = d as NSDate
let formattedString = formatter.stringFromDate(date)
println("\(formattedString)")
}
Now all of that is in Swift but I am sure it's intuitive enough to write the same code in Objective-C.
The console output:
Convert time string to NSDate
t = 3:30 PM converted as Optional(2000-01-01 15:30:00 +0000)
t = 4:00 PM converted as Optional(2000-01-01 16:00:00 +0000)
t = 4:30 PM converted as Optional(2000-01-01 16:30:00 +0000)
t = 5:00 PM converted as Optional(2000-01-01 17:00:00 +0000)
t = 12:30 PM converted as Optional(2000-01-01 12:30:00 +0000)
t = 12:00 PM converted as Optional(2000-01-01 12:00:00 +0000)
t = 1:00 PM converted as Optional(2000-01-01 13:00:00 +0000)
t = 1:30 PM converted as Optional(2000-01-01 13:30:00 +0000)
t = 2:00 PM converted as Optional(2000-01-01 14:00:00 +0000)
t = 3:00 PM converted as Optional(2000-01-01 15:00:00 +0000)
Sort array of NSDate objects
12:00 PM
12:30 PM
1:00 PM
1:30 PM
2:00 PM
3:00 PM
3:30 PM
4:00 PM
4:30 PM
5:00 PM
Your keys are strings, and you are doing a lexicographically comparison of the strings. In that comparison, 1:00 is less than 12:30 becacuse : is less than 2.
If you want to sort by dates, you will first need to convert it to a type that can actually convey the time value in a conversion. This could be NSDate, or a simple integer representing an offset from midnight.
A simple comparator can do
NSArray *sortedAllKeys = [[events allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat =#"h:mm a";
[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"en_US.POSIX"] ];
});
return [[formatter dateFromString:obj1] compare:[formatter dateFromString:obj2]];
}];
Technical Note QA1480 might be interesting for you.
I having a problem when convert String to Date in Blackberry SDK. Please support for me.
This is my code:
String date = "Mon May 09 09:00:00 GMT 2011";
Date formatter = new Date();
formatter.setTime(HttpDateParser.parse(date));
SimpleDateFormat dateFormat = new SimpleDateFormat(formatStr);
string dateString = dateFormat.format(formatter);
purpsoe of the function is format date MMM dd, YYYY.
But after i run the function, it will return result that I unexpected.
Expected: May 09, 2011
UnExpected : Jan,01,1970.
I suspect the "Mon May 09 09:00:00 GMT 2011" is not a supported by HttpDateParser date format. Since the HttpDateParser.parse() does not throw an exception, I guess it simply return 0 in case of an unsupported format.