gpt4 book ai didi

ios - 用于存储日期的 CoreData 推荐做法

转载 作者:搜寻专家 更新时间:2023-11-01 05:46:11 25 4
gpt4 key购买 nike

我正在制作一个简单的类次跟踪器/工资计算器来练习 CoreData 和 Swift。我遇到了与此相关的不同任务的问题,因为我需要使用日期来:

  • 显示它们
  • 检查一周内的轮类次数,看看您是否应该得到额外的报酬(如果您当周工作超过 12 小时,挪威规定每小时额外加薪 5/10 美元)
  • 将一个月内的所有工资加在一起 ​​
  • 如果用户输入错误,则删除数据

  • 可能还有更多我忘记了。

    截至目前,我正在从日期选择器获取数据,这些数据选择器使用日期格式化程序将它们添加到 DB 中作为“fromDate”和“toDate”作为字符串。这导致我不得不使用一堆糟糕的代码。很大程度上是因为 NSDate 时区问题等。

    我应该如何布置我的数据库才能最有效地做到这一点?我应该为我需要的每种类型的数据创建一个字段吗? ('fromMinute'|'fromHour'|'fromDay'|'fromWeek'|'fromMonth'|'fromYear') 然后对应于'to'字段?我是数据库的新手,但我认为我不应该拥有那么多领域。我应该有一个月份表,然后是一个周表,然后使用关系(在这种情况下我该怎么做?)

    我不能只使用时间间隔,因为奖金取决于时间有多晚。

    希望有人可以帮助我解决一些关于 CoreData 的推荐实践

    更新:

    这是我的 super 复杂的核心数据模型!
    enter image description here

    以及一个 NSManagedObject 类(我认为)
    import UIKit
    import CoreData

    @objc(Shifts)

    class Shifts: NSManagedObject {
    @NSManaged var fromDate : String
    @NSManaged var toDate : String

    func getShift () -> Shift{
    let formatter = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd w W HH:mm"
    let from:NSDate = formatter.dateFromString(self.fromDate)!
    let to:NSDate = formatter.dateFromString(self.toDate)!
    let length:Double = to.timeIntervalSinceDate(from) as Double / 60

    let newShift = Shift(from:from,to:to,length:length)
    return newShift
    }


    }

    Shit 是我的 View Controller 中的一个类,我用来显示等我的数据,它看起来像这样 (TW:Code Gore)
    class Shift {
    var fromDate : NSDate
    var toDate : NSDate
    var length : Double //In Minutes
    var salary : Double = Double()
    var UB : Bool = false

    let etter18hverdag:Double = 22
    let etter21hverdag:Double = 45
    let helligdag:Double = 90
    let helgEtter13:Double = 45
    let helgEtter16:Double = 90 //HUSK AT PAUSE FINNES


    init (from : NSDate, to : NSDate, length:Double){
    self.fromDate = from
    self.toDate = to
    self.length = length
    }
    func calcSalary(ub: Bool)->Double{

    let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
    let hour: Double = userDefaults.doubleForKey("salary")

    println("Checking salary on shift fromDate:\(fromDate) with length:\(length). Shift UB: \(UB)")

    if (ub){
    let calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
    calendar.locale = NSLocale.systemLocale()
    calendar.timeZone = NSTimeZone.localTimeZone()

    var checkTime:NSDate = fromDate
    var checkToTime:NSDate = toDate

    var totalSalary:Double = Double()

    while (checkToTime.timeIntervalSinceDate(checkTime)>0.0){

    let split = calendar.components(NSCalendarUnit.WeekdayCalendarUnit | NSCalendarUnit.HourCalendarUnit, fromDate: checkTime)

    println("Checking: \(checkTime) to: \(checkToTime) diff:\(checkToTime.timeIntervalSinceDate(checkTime)) currentSal: \(totalSalary) splitTime:\(split.hour)")
    if(split.weekday==7){ //Søndag
    let lønn = hour + helligdag
    totalSalary += (lønn/4)
    }

    else if (split.weekday == 6){ //Lørdag
    if(split.hour < 13){
    let lønn = hour
    totalSalary += (lønn/4)
    }
    if (split.hour>13 && split.hour<16){
    let lønn = hour + helgEtter13
    totalSalary += (lønn/4)

    }
    if (split.hour > 16){
    let lønn = hour + helgEtter16
    totalSalary += (lønn/4)
    }

    }

    else if (split.weekday < 6){ //Hverdag
    if(split.hour < 18){
    let lønn = hour
    totalSalary += (lønn/4)

    }
    if (split.hour>18 && split.hour<21){
    let lønn = hour + etter18hverdag
    totalSalary += (lønn/4)

    }
    if (split.hour > 21){
    let lønn = hour + etter21hverdag
    totalSalary += (lønn/4)
    }
    }


    checkTime = checkTime.dateByAddingTimeInterval(15*60) //15 min ganger 60 sek i min
    }
    println("Calculated salary WITH UB: \(totalSalary)")

    return totalSalary
    } else {
    let calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
    calendar.locale = NSLocale.systemLocale()
    calendar.timeZone = NSTimeZone.localTimeZone()

    var checkTime:NSDate = fromDate
    var totalSalary:Double = Double()
    let multiple = (length/60)

    while (self.toDate.timeIntervalSinceDate(checkTime)>0.0){

    let lønn = hour
    totalSalary += (lønn/4)

    checkTime = checkTime.dateByAddingTimeInterval(15*60) //15 min ganger 60 sek i min
    }
    println("Calculated salary WITHOUT UB: \(totalSalary)")
    return totalSalary
    }
    }

    最佳答案

    简短版本
    最佳做法是存储 fromDatetoDateNSDate s。
    长版
    约会有什么?
    NSDate实际上是一个 NSTimeInterval自引用日期起。 NSTimeInterval value 表示自该日期以来的秒数,与时区、日历或任何其他地理或政治结构无关。从概念上讲,这与 unix 时间戳相同,但 unix 时间戳使用不同的引用日期(相当于 timeIntervalSince1970)。 NSDate 代表一个时间点——天、年、时区和夏令时都是表示级别的问题,而 NSDate 只是一个值对象。它是日期表示的蜜獾。它不在乎。
    也就是说,显示 NSDate涉及许多其他组件,大多数与本地化有关。用户的本地化设置决定了使用哪种日历表示 ( NSCalendar ),以及日期的视觉格式 ( NSDateFormatter )。用户甚至可以在您的应用程序运行时更改这些设置,这就是为什么会有一些系统通知来通知您的应用程序发生了更改。
    使用 NSCalendar 执行日期计算把上面的概念搞懂了就不难了,去年NSCalendar被扩展为更易于使用(不幸的是,这些改进最近才出现在 iOS 上)。 Apple 在 Date and Time Programming Guide: Performing Calendar Calculations 中有很好的日历计算指南,以及去年 WWDC 的一个 session ,WWDC 2013: Solutions to Common Date and Time Challenges ,详细介绍了对 NSCalendar 的改进并涵盖了一些非常好的处理日期的一般技巧。
    如果您的数据模型将日期存储为 NSDate为用户的本地化设置正确调整日期值的视觉呈现要容易得多。该模型不需要知道时区、日历和本地化设置——这些最好在表示( View 或 View Controller )级别处理。
    如果您将日期存储为字符串、日期组件或日历组件,您会遇到很多问题。例如,如果当前日历更改,则所有持久化数据都将无效,需要重新构建。夏令时也可能是一个大问题。
    这如何影响核心数据?
    在您的情况下,您表示模型中的日期范围(从 fromDatetoDate 的秒范围)。有一些表示相同事物的替代方法,例如使用 fromDate和一个 duration表示 NSTimeInterval来自 fromDate每当类次结束时。这两种方法都有效。
    在查询特定小时的数据时,首先您将执行必要的日历计算以获取用户当前语言环境中小时的开始和结束。
    例如,在objective-c 中,使用新的NSCalendar方法:

    NSCalendar  *calendar   = [NSCalendar autoupdatingCurrentCalendar];
    NSDate *startOfDay = [calendar startOfDayForDate:fromDate];
    NSDate *startOfHour= [calendar dateByAddingUnit:kCFCalendarUnitHour value:8 options:NSCalendarMatchStrictly];
    NSDate *endOfHour = [calendar dateByAddingUnit:kCFCalendarUnitHour value:9 options:NSCalendarMatchStrictly];
    这将为您提供 fromDate 当天第 8 小时的开始和结束时间。下降。这只是一个示例,您的业务规则可能会规定更多的逻辑,例如根据 fromDate 检查 toDate 的值等 - 尽管其中许多问题最好通过自定义 Core Data validation 来处理。 .
    在谓词中使用它是一组简单的数字比较:
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.fromDate <= %@ AND SELF.fromDate >= %@", endOfHour, startOfHour];
    使用 NSFetchedResultsController 时要显示部分, sectionNameKeyPath可以指向 Core Data transient 属性,以允许您根据需要显示基于小时、月等的部分。排序和分组查询结果不能使用 transient 属性,只能使用由建模属性支持的属性 - 在您的情况下, fromDatetoDate .由于日期是数字并代表一个时间点,因此这对于许多业务规则来说都很容易。

    关于ios - 用于存储日期的 CoreData 推荐做法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25605046/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com