This question already has answers here:
NSDate() or Date() shows the wrong time
(2 answers)
Closed 4 years ago.
I created an object that has a creation date property. The date property is calculated by using the Date() function, for getting the current date and time.
The date is correct but the time is 3 hours behind the clock of the simulator. How can I fix this?
The system displays the current date / time of UTC/GMT.
To get time/date for local time zone. use following code:
let currentDate = Date()
//7/29/18, 9:09 PM
print (DateFormatter.localizedString(
from: currentDate,
dateStyle: .short,
timeStyle: .short))
//Sunday, July 29, 2018 at 9:09:27 PM India Standard Time
print (DateFormatter.localizedString(
from: currentDate,
dateStyle: .full,
timeStyle: .full))
//Jul 29, 2018 at 9:09:27 PM
print (DateFormatter.localizedString(
from: currentDate,
dateStyle: .medium,
timeStyle: .medium))
Above code is tested in India at 09:09 PM on 29th July 2018.
Related
I am trying to implement a simple countdown timer in my test app.
I have two dates:
fromDate - which is current time that I get by Date(), e.g. 2021-08-27 11:07:34 +0000
toDate - is a future date, e.g. 2021-11-17 01:00:00 +0000
I am using DateComponents to get back the difference in days, hours, minutes and seconds.
let components = Calendar.current.dateComponents([.day, .hour, .minute, .second],
from: fromDate,
to: toDate)
Its returning me back the values for days hours minute and second 81, 12, 52, 25
The values for day, minute and second are correct, but the hour is 1 hour less.
I suspect daylight timing has to do something with this but I cannot find anything that can help here.
Kindly help me what I am doing wrong as I have tried many things in past few days but nothing seems to work
I was able to reproduce the behaviour by using:
let from = Date(timeIntervalSince1970: 1630062455)
print(from) // 2021-08-27 11:07:35 +0000
let to = Date(timeIntervalSince1970: 1637110800)
print(to) // 2021-11-17 01:00:00 +0000
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(identifier: "Europe/London")!
let comp = calendar.dateComponents([.day, .hour, .minute, .second], from: from, to: to)
print(comp.day!, comp.hour!, comp.minute!, comp.second!)
The reason why this happens is because when doing dateComponents(_:from:to:), Calendar takes into account its timezone. After all, without a timezone, (almost) no date components would make sense - you would not be able to tell what hour a Date is, for example. A Date just represents an instant in time/n seconds since the epoch.
(In the case of Calendar.current, the timezone it uses is TimeZone.current)
Europe/London would go out of DST at some point between from and to. This means the calendar would calculate the difference in date components between:
from: 2021-08-27 12:07:35
to: 2021-11-17 01:00:00
Notice that the first time is 12:07:35, rather than 11:07:35. This is because at 2021-08-27 11:07:35 +0000, the local date time at Europe/London really is 2021-08-27 12:07:35.
To get your desired output, just change the calendar's timeZone to UTC:
var calendar = Calendar.current
calendar.timeZone = TimeZone(identifier: "UTC")!
let comp = calendar.dateComponents([.day, .hour, .minute, .second], from: from, to: to)
I am working with Calendar and I am able to get some things in that for this current year, I have Jan, feb, march, April, may, June, July ... up to December. But now since we are in May, I do not want to see June, July, Aug .... up to December. Rather I want to see Jan, feb, march, April, may and be able to scroll backwards to probably ... Nov, 2020, Dec, 2020 With the current implementation of Calendar I do not understand how to pick this out.
This is what I use to get my Months currently private let months = Calendar.current.shortMonthSymbols.map { $0.uppercased() }
Which results into Jan, feb, march, April, may, June, July ... up to December how can I change this behaviour to reflect what I want?
Use an enumerator on the array and then use prefix(while:) to get all months up to the current one.
let thisMonth = Calendar.current component(.month, from: Date())
let currentYearMonths = Calendar.current.shortMonthSymbols.enumerated()
.prefix(while: { $0.offset < thisMonth })
.filter { $0.offset < thisMonth }
.map(\.element.localizedUppercase)
For the previous year part, calculate last year and then simply join the year to the elements of .shortMonthSymbols using map
let aYearAgo = Calendar.current.date(byAdding: .year, value: -1, to: Date())!
let lastYear = Calendar.current.component(.year, from: aYearAgo)
let lastYearMonths = Calendar.current.shortMonthSymbols.map { "\($0.localizedUppercase), \(lastYear)"}
I'm trying to find the first day of the month. There have been different solutions posted here on SO (e.g. this)
When analyzing them it seems like the day component is being ignored.
Instead of returning the first day of the month
Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
it returns the current day but changes the month:
(lldb) po Calendar.current.date(from: Calendar.current.dateComponents([.year, .month], from: Calendar.current.startOfDay(for: self)))!
▿ 2019-02-28 23:00:00 +0000
- timeIntervalSinceReferenceDate : 573087600.0
(lldb) po self
▿ 2019-03-28 01:09:17 +0000
- timeIntervalSinceReferenceDate : 575428157.663583
I've also looked into setting the components by hand:
var components = Calendar.current.dateComponents([.year, .month, .day], from: self)
components.setValue(1, for: .day)
let value = Calendar.current.date(from: components)!
which results in the same:
(lldb) po value
▿ 2019-02-28 23:00:00 +0000
- timeIntervalSinceReferenceDate : 573087600.0
Am I doing something wrong? Or is this a bug in Calendar?
Apple Swift version 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)
Target: x86_64-apple-darwin18.6.0
Oh in case this is interesting I'm developing for macOS but as far as I can see, this API is not influenced by Catalina.
Your code is fine. You have a date that is in March 2019. You create a new date that is March 1, 2019 at midnight local time. All good so far.
The only issue is your misunderstanding of the output of printing that date. The date is printed in the debugger in UTC time. That's what the +0000 means - UTC time. You must live in the UTC+1 timezone.
So March 1, 2019 at midnight your local time is the same as February 28, 2019 at 23:00 UTC. It's the same moment in time, just displayed in a different timezone.
In short, your code is fine.
I am trying to get a Date object for the next occurring future time where the hour in UTC time is 18. However my code doesn't work as expected. I have the following:
let dateComponents = DateComponents(timeZone: TimeZone(abbreviation: "GMT"), hour: 18)
let date = Calendar.current.nextDate(after: Date(), matching: dateComponents, matchingPolicy: .nextTime)
print(date)
The problem is that this results in 2019-02-09 23:00:00 +0000
The date is for the next occurring time where the hour is 18 in EST.
I would have expected, since the the dateComponents has the timezone set to UTC and the hour to 18, that the date would be 2019-02-09 18:00:00 +0000. Furthermore, changing the timezone seems to have no effect on the nextDate found.
Why doesn't the nextDate function respect the timezone set in the dateComponents passed to it?
It looks like the timezone in DateComponents is ignored.
However when you set the timezone in a new calendar you get correct results.
let dateComponents = DateComponents(hour: 18)
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
let date = calendar.nextDate(after: Date(), matching: dateComponents, matchingPolicy: .nextTime)
print(date) // Optional(2020-09-29 18:00:00 +0000)
I live in GMT time, and running this in a playground produces the expected result you are looking for. You are setting the time zone of your date component, but I would imagine your own calendar (Calendar.current) is set to EST. You would need to account for the offset in EST vs GMT for your required result
This question already has answers here:
How to get previous and next month in calendar-Swift
(6 answers)
Closed 5 years ago.
I have a problem about showing specific date. Here the case, I have a random date from my API (06/16/2015) that always change. I put it into variable name toDate with Date type. I need to get 30 days before the toDate for my fromDate variable.
I read this but it's still not working. Note: I don't have any DatePicker in this controller.
Here you go:
let toDate = `your date object`
let fromDate = Calendar.current.date(byAdding: .month, value: -1, to: toDate)
or,
// If you want to have exactly 30 days before
let fromDate = Calendar.current.date(byAdding: .day, value: -30, to: toDate)
You can use the following code:
let today = Date() //Jun 21, 2017, 7:18 PM
let thirtyDaysBeforeToday = Calendar.current.date(byAdding: .day, value: -30, to: today)! //May 22, 2017, 7:18 PM
I hope this helps.