- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当 GMT 和用户时区中的日期不同并且日期时间的差异小于 24 小时(即使有不同的日期)时,我一直无法获得两个日期时间之间的一致日期列表或计数。我用谷歌搜索并不断尝试不同的方法,但我无法弄清楚。当用户想要使用多个时区时,它甚至更难看,但我认为一旦我明白我在这里做错了什么,我就可以解决这个问题。
在我的应用程序中,我从多个时区的用户处获取日期,将它们存储为字符串,例如:2017-12-08 12:30:00 +0900
然后我尝试在开始日期和结束日期之间创建一个日期数组。但是,我无法让数组包含所有实际日期。
首先,我尝试在第一天和最后一天之间直接展开一个数组:(这适用于我的项目,但不适用于 Playground ??我不知道为什么。
func getMyDates(_ start:String,_ end: String) -> [Date]? {
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let fromDate = dateFormatter.date(from: start)
let toDate = dateFormatter.date(from: end)
var dates = [Date]()
dates.append(fromDate!)
dates.append(toDate!)
print(dates)
return dates
}
func getDays() -> [Date]? {
guard let dates = getMyDates() else {return nil}
print("getDays got \(dates) from getMyDates()")
var userdates = dates
let fromDate = dates[0]
let toDate = dates[1]
print("changed it to: \(fromDate ... toDate)")
return fromDate ... toDate
}
如果用户的第一个和最后一个日期对于他们的时区和格林威治标准时间相同,则此方法有效。例如,如果字符串条目是:2017-11-08 12:30:00 +0900 和 2017-11-10 23:30:15 +0900,则输出包括三个预期日期。
//getDays got [2017-11-08 03:30:00 +0000, 2017-11-10 14:30:15 +0000] from getMyDates()
//changed it to: [2017-11-08 03:30:00 +0000, 2017-11-09 03:30:00 +0000, 2017-11-10 03:30:00 +0000]
但是,当第二个日期时间早于第一个时,它将失败,例如:2017-12-08 12:30:00 +0900 和 2017-12-09 09:30:15 +0900。在那种情况下,我只能休息 1 天:
//getDays got [2017-12-08 03:30:00 +0000, 2017-12-09 01:00:00 +0000] from getTripDates()
//changed it to: [2017-12-08 03:30:00 +0000]
然后,我尝试按照 This question 中的建议计算它们之间的天数,但我遇到了同样的问题,因为第一个算 2 天,第二个算 0 天。我的计划是计算天数并使用 this approach .
我认为这是一个时区问题,但我不知道如何解决。我已尝试将时区设置为 .current,但未将其设置为 .current。
我不能任意添加一天,因为当第一个日期时间早于第二个日期时间时,这将失败(例如 2017-12-08 12:30:00 +0900 和 2017-12-09 15:30: 15 +0900。
使用@malik 的建议似乎行得通,但不知何故行不通。我们得到相同的行为。如果第二个日期时间 TIME 在当天晚些时候,则不需要额外的一天(并且以某种方式剩余的秒数不起作用 - 给出了太多天数。
//in playground swift4
import UIKit
let start = "2017-12-08 12:30:00 +0900"
let end = "2017-12-10 13:30:00 +0900"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
var fromDate = dateFormatter.date(from: start)
let toDate = dateFormatter.date(from: end)
let cal = Calendar.autoupdatingCurrent
let seconds=cal.dateComponents([.second], from: fromDate!, to: toDate!)
var days = Int(seconds.second ?? 0)/(86400)
//days prints 2
//if (Int(seconds.second ?? 0) % (86400)) > 0 {
// days += 1
//}
var newDates = [Date]()
newDates.append(fromDate!)
for _ in 1 ... days {
let daysBetween = cal.date(byAdding: .day, value: 1, to: fromDate!)
fromDate = daysBetween
newDates.append(fromDate!)
}
//print(newDates)
期望的输出:
// [2017-12-08 03:30:00 +0000, 2017-12-09 03:30:00 +0000, 2017-12-10 03:30:00 +0000]
但是:如果我将结束日期更改为:
let end = "2017-12-10 09:30:00 +0900"
输出错误:
//[2017-12-08 03:30:00 +0000, 2017-12-09 03:30:00 +0000]
在这种情况下,为不完整的日子添加额外的一天会有所帮助(取消注释逻辑:)
if (Int(seconds.second ?? 0) % (86400)) > 0 {
days += 1
}
正确产生:
//[2017-12-08 03:30:00 +0000, 2017-12-09 03:30:00 +0000, 2017-12-10 03:30:00 +0000]
但是:如果我在保留逻辑的同时改回 end,我会得到:
//[2017-12-08 03:30:00 +0000, 2017-12-09 03:30:00 +0000, 2017-12-10 03:30:00 +0000, 2017-12-11 03:30:00 +0000]
我认为它会很好,但由于额外的一天,它会扰乱我后来的电话,看看那些日子还有什么事情发生,因为额外的一天不在原始数据中。
所以,也许我只需要设置一些 HH:mm 字符串的比较?这对我来说没有意义。我觉得我遗漏了一些明显的东西,这些东西可以让我在用户的语言环境中扩展日期。
使用@malik 的修改建议,该建议减少了小时数,然后计算天数。然后,我可以遍历天数来创建一个数组。
最佳答案
与时区无关。通过这两个链接,您的计划是正确的。唯一的问题是您提供的第一个链接计算的天数没有考虑小时、分钟、秒等细粒度细节。既然你想要细粒度的,你需要做的就是用 .second
.day
extension Date {
func secondsBetweenDateTimes(toDateTime: Date) -> Int {
let components = Calendar.current.dateComponents([.second], from: self, to: toDateTime)
return components.second ?? 0
}
}
这将返回两个日期时间之间的总秒数。接下来,您需要将此方法的结果除以 86400
(一天中的秒数)以获得天数。然后使用余数,将其除以 24
得到剩余的小时数,依此类推。这样,您可以获得两个日期时间之间的确切差异。
更新
您的 if 检查有点错误。我看到您在这里尝试做什么,但这不是正确的 if check
。现在你告诉你的代码做的是如果秒数不能分成整天,那么几乎要多加一天。结果,您将看到您现在正在经历的行为。在我原来的回答中,我说过要使用 remainder
而不是整个值来决定是否要添加一天。不管怎样,既然你没有使用小时、分钟、秒作为你的决定因素,你可以用另一种方式来做。计算前去掉时分秒,计算天数如下。
let start = "2017-12-08 12:30:00 +0900"
let end = "2017-12-10 13:30:00 +0900"
let startDate = start.substring(to: start.index(start.startIndex, offsetBy: 10))
let endDate = end.substring(to: end.index(end.startIndex, offsetBy: 10))
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
var fromDate = dateFormatter.date(from: startDate)
let toDate = dateFormatter.date(from: endDate)
let cal = Calendar.autoupdatingCurrent
let days=cal.dateComponents([.day], from: fromDate!, to: toDate!)
print(days.day) //Prints 2
关于swift - 我怎样才能始终如一地获取 swift4 中两个日期之间所有天数的计数或列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46601151/
在过去的一个月里,我注意到出现在我的应用程序中的广告(实际上我每天都在使用我的应用程序)是同一个广告。 广告由 AdMob 提供,但我担心如果广告保持不变,我将无法从其他用户那里获得收入。 知道为什么
我是一名优秀的程序员,十分优秀!