Is there a way to customize the date formatter as per our requirements in swift iOS - nsdateformatter

I want to display a date in my viewcontroller as January 1-7,2005, which in-turn represents the dates of the current week like 1-7, 8-14.... But i am not finding how to customize the date formatter to have this format.

You can use the DateFormatter() function
let date = Date() // Gets current date
let dateFormatter = DateFormatter()
let monthInt = Calendar.current.component(.month, from: date) // Gets the current month number
let monthStr = Calendar.current.monthSymbols[monthInt-1] // Month to string
dateFormatter.dateFormat = "dd-M,YYYY"
let dateString = dateFormatter.string(from: date)
print("\(monthStr) \(dateString)")
Output: June 29-6,2020
Ensure your dateFormat conforms to ISO 8601 https://www.w3.org/TR/NOTE-datetime

Related

SimpleDateFormat showing a.m./p.m. instead of AM/PM

I am trying to use SimpleDateFormat to display the time as 12:00:00 AM. Here is what I am doing:
val timeFormat = SimpleDateFormat("hh:mm:ss a")
val timeString = timeFormat.format(Date(transaction.time))
According to these docs a should show AM/PM
timeString come out in the format: 12:00:00 a.m.
How can I make it show AM instead of a.m.?

How do I return the local time portion of a string given a date string

I am wanting to display in a react native app a date given by the API.
The API is returning the following value:
"2022-06-20T14:00:00.000"
I need to display to the user
2:00 PM
The problem is that when I try this:
const dateString = "2022-06-20T14:00:00.000"
const date = new Date(dateString);
console.log(date)
The date has been changed to:
2022-06-20T14:00:00.000Z
Meaning it is 2pm UTC time when it should be 2pm local time.
On the end of the new Date variable, if you add the .toLocaleTimeString(), it should then output as 2:00:00PM.
const date = new Date(dateString).toLocaleTimeString();
you can use moment library with its localized formats,
here is the documentation for more of its formats https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format/
const dateString = "2022-06-20T14:00:00.000"
console.log(moment(dateString).format('LT'))

How do you compare selector attributes in Testcafe?

I'm trying to compare the date of videos on a webpage to today's date. If the difference between the two dates is more than X days, report back as false.
The videos on the webpage have a tag in them which uses the format yyyy-mm-dd
I've got a selector set up to find the videos const videoDate = Selector('OPTA-video').withAttribute('data-secondary-time')
Now how do I set a variable to today's date and compare the two? I'm completely stuck!
I was using Katalon Studio before and here's the groovy script that did the same job:
String videoDate = WebUI.getAttribute(findTestObject('OPTA-video'), 'data-secondary_time')
LocalDate todaysDate = LocalDate.now()
LocalDate videoDateParsed = LocalDate.parse(videoDate, dtf)
if (ChronoUnit.DAYS.between(videoDateParsed, todaysDate) > 1) {
KeywordUtil.markFailed('The videos are 2+ days old.')
} else {
KeywordUtil.logInfo('The videos are up to date.')
}
You can use the getAttribute TestCafe method to access an attribute value. Then, parse the attribute value into the JavaScript Date object:
String videoDate = Selector('OPTA-video').getAttribute('data-secondary-time');
Date videoDateParsed = Date.parse(videoDate);
Date todaysDate = Date.now()
...
In the following thread you can find how to compare Date objects.
This is one of the scripts that I am using.
//getting your XPath test value into a string
String ann_time =
WebUI.getText(findTestObject("ObjectRepository/navigateTOElement/announcements_date"))
//converting time to simple date format
SimpleDateFormat sdf = new SimpleDateFormat('HH:mm')
Date sdf_anntime = sdf.parse(new String(ann_time))
//getting Current time
SimpleDateFormat dateFormatGmt = new SimpleDateFormat('HH:mm')
dateFormatGmt.setTimeZone(TimeZone.getTimeZone('GMT'))
SimpleDateFormat dateFormatLocal = new SimpleDateFormat('HH:mm')
currDate = dateFormatLocal.parse(dateFormatGmt.format(new Date()))
// time gap in long format
long duration = currDate.getTime() - sdf_anntime.getTime()
//time gap to mins
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(duration)
//compare time gap with globale variable
if (diffInMinutes < GlobalVariable.News_updated_time) {
log.logInfo("system is getting updated,last updated "+ diffInMinutes + "min ago")
} else {
CustomKeywords.'errorMessage.logFailed.markStepFailed'('from 1 h, system was not updated')
log.logInfo('from '+ diffInMinutes+ 'h, system was not updated')
}

NSDateFormatter timeIntervalSince1970 strange behavior with milliseconds

I'm trying to parse a date with milliseconds using NSDateFormatter, and I'm getting weird results when I print out its time interval since 1970. Here's my test code:
var timeStr = "2015-09-29 14:32:42.297-07"
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSx"
let date = dateFormatter.dateFromString(timeStr)!
let dateFormatted = String(format: "%.20f", date.timeIntervalSince1970)
print("date: \(dateFormatted)")
Result: "date: 1443562362.29699993133544921875\n"
Instead of ending with 297, it ends with something close to it. Why?
Seems this is just how doubles work. It's not related to NSDateFormatter. If I make a double with value 2.3 then print it to 20 decimal places, I get 2.99999990453636... or something.

Truncate NSDate (Zero-out time)

I want to generate a new NSDate with 0 hours, 0 minutes, and 0 seconds for time. The source date can be any random NSDate.
Is there a way to achieve this? The documentation did not help me with this.
Example
Have: 2010-10-30 10:14:13 GMT
Want: 2010-10-30 00:00:00 GMT
unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date];
NSDate* dateOnly = [calendar dateFromComponents:components];
date is the date you want to remove the time from.
This separates the date and time and creates a new date with the default time (00:00:00).
EDIT
To take time zone into account:
NSDate* dateOnly = [[calendar dateFromComponents:components] dateByAddingTimeInterval:[[NSTimeZone localTimeZone]secondsFromGMT]];
Use NSCalendar's rangeOfUnit:startDate:interval:forDate:. This code will choose the day boundary based on the current time zone. If you want a particular time zone, you need to create an NSCalendar and set its time zone appropriately.
- (NSDate*)boundaryForCalendarUnit:(NSCalendarUnit)calendarUnit
{
NSDate *boundary;
[[NSCalendar currentCalendar] rangeOfUnit:calendarUnit startDate:&boundary interval:NULL forDate:self];
return boundary;
}
- (NSDate*)dayBoundary
{
return [self boundaryForCalendarUnit:NSDayCalendarUnit];
}
With Swift 3, you can choose one of the four following patterns in order to solve your problem.
#1. Using Calendar startOfDay(for:)
startOfDay(for:) has the following declaration:
func startOfDay(for date: Date) -> Date
Returns the first moment of a given Date, as a Date.
The Playground code below shows how to use this method:
import Foundation
let date = Date()
// Get new date
let calendar = Calendar.current
let newDate = calendar.startOfDay(for: date)
// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long
let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate)
// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST
#2. Using Calendar date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:)
date(bySettingHour:minute:second:of:matchingPolicy:repeatedTimePolicy:direction:) has the following declaration:
func date(bySettingHour hour: Int, minute: Int, second: Int, of date: Date, matchingPolicy: Calendar.MatchingPolicy = default, repeatedTimePolicy: Calendar.RepeatedTimePolicy = default, direction: Calendar.SearchDirection = default) -> Date?
Returns a new Date representing the date calculated by setting hour, minute, and second to a given time on a specified Date.
The Playground code below shows how to use this method:
import Foundation
let date = Date()
// Get new date
let calendar = Calendar.current
let newDate = calendar.date(bySettingHour: 0, minute: 0, second: 0, of: date)
// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long
let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate!)
// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST
#3. Using Calendar dateComponents(_:from:) and date(from:) methods
dateComponents(_:from:) has the following declaration:
func dateComponents(_ components: Set<Calendar.Component>, from date: Date) -> DateComponents
Returns all the date components of a date, using the calendar time zone.
date(from:) has the following declaration:
func date(from components: DateComponents) -> Date?
Returns a date created from the specified components.
The Playground code below shows how to use those methods:
import Foundation
let date = Date()
// Get new date
let calendar = Calendar.current
let components = calendar.dateComponents([.day, .month, .year], from: date)
let newDate = calendar.date(from: components)
// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long
let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate!)
// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST
#4. Using NSCalendar range(of:start:interval:for:)
range(of:start:interval:for:) has the following declaration:
func range(of unit: NSCalendar.Unit, start datep: AutoreleasingUnsafeMutablePointer<NSDate?>?, interval tip: UnsafeMutablePointer<TimeInterval>?, for date: Date) -> Bool
Returns by reference the starting time and duration of a given calendar unit that contains a given date.
The Playground code below shows how to use this method:
import Foundation
let date = Date()
// Get new date
let calendar = Calendar.current as NSCalendar
var newDate: NSDate?
calendar.range(of: .day, start: &newDate, interval: nil, for: date)
// Format dates
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_UK")
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .long
let formattedDate = dateFormatter.string(from: date)
let formattedNewDate = dateFormatter.string(from: newDate as! Date)
// Print formatted dates
print(formattedDate) // Prints: 30/03/2017, 15:14:41 CEST
print(formattedNewDate) // Prints: 30/03/2017, 00:00:00 CEST
I know its late, but there are now better methods:
why dont you just use
Swift 2
NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: yourDateToZeroOutTime, options: [])
Swift 5
var yourDate = Date() //Or any Date
yourDate = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: yourDate) ?? yourDate
Swift 3
extension Date {
func trimTime() -> Date {
var boundary = Date()
var interval: TimeInterval = 0
_ = Calendar.current.dateInterval(of: .day, start: &boundary, interval: &interval, for: self)
return Date(timeInterval: TimeInterval(NSTimeZone.system.secondsFromGMT()), since: boundary)
}
}
I would use the description method to get the given date as a string, then modify the string and create your new date with initWithString.
initWithString:
Returns an NSDate object initialized with a date and time value specified by a given string in the international string representation format.
(id)initWithString:(NSString *)description
Parameters
description
A string that specifies a date and time value in the international string representation format—YYYY-MM-DD HH:MM:SS ±HHMM, where ±HHMM is a time zone offset in hours and minutes from GMT (for example, “2001-03-24 10:45:32 +0600”).
You must specify all fields of the format string, including the time zone offset, which must have a plus or minus sign prefix.
Return Value
An NSDate object initialized with a date and time value specified by aString.