Osc*_*and 1 sql sqlite core-data ios swift
我正在制作一个简单的移位跟踪器/工资计算器来练习CoreData和Swift.我遇到与此相关的不同任务的问题,因为我需要使用日期:
也许更多我忘了.
截至目前,我从日期选择器获取数据,使用日期格式化程序将数据库添加为"fromDate"和"toDate"作为字符串.这导致我不得不使用一堆坏代码.很多是因为NSDate时区问题等.
我应该如何布置我的数据库以最有效地做到这一点?我应该为我需要的每种类型的数据创建一个字段吗?('fromMinute'|'fromHour'|'fromDay'|'fromWeek'|'fromMonth'|'fromYear')然后对应'to'字段?我是数据库的新手,但我不认为我应该有那么多领域.我应该有月份表,然后是周表,然后使用关系(在这种情况下我该怎么做?)
我不能只使用时间间隔,因为奖金取决于它有多晚.
希望有人可以帮我解决一些关于CoreData的推荐做法
更新:
这是我超级复杂的核心数据模型!

以及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
}
}
Run Code Online (Sandbox Code Playgroud)
狗屎是我在视图控制器中的一个类,我用它来显示我的数据,它看起来像这样(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
}
}
Run Code Online (Sandbox Code Playgroud)
que*_*ish 13
最好的做法是存储fromDate和toDate作为NSDates.
一个NSDate实际的是NSTimeInterval,因为参考日期.该NSTimeInterval值表示自该日期以来的秒数,并且无论时区,日历或任何其他地理或政治结构如何.从概念上讲,这与unix时间戳相同,但unix时间戳使用不同的引用日期(相当于timeIntervalSince1970).NSDate表示一个时间点 - 天,年,时区和夏令时都是表示级别的问题,而NSDate只是一个值对象.这是日期陈述的蜜獾.它不在乎.
也就是说,显示NSDate涉及许多其他组件,大多数与本地化有关.用户的本地化设置确定使用哪个日历表示(NSCalendar),以及如何直观地格式化日期(NSDateFormatter).用户甚至可以在应用程序运行时更改这些设置,这就是为什么有一些系统通知可以通知您的应用程序已发生更改.
NSCalendar一旦你很好地理解了上述概念,使用日期计算并不太难,并且去年NSCalendar扩展到更容易使用(不幸的是,这些改进仅在最近才出现在iOS上).Apple在日期和时间编程指南:执行日历计算,以及去年WWDC,WWDC 2013:常见日期和时间挑战解决方案的会话中有详细的日历计算指南,详细介绍了改进NSCalendar并涵盖了一些非常好的技巧.一般的日期工作.
如果您的数据模型存储日期,NSDate则更容易根据用户的本地化设置调整日期值的可视化表示.该模型不需要知道时区,日历和本地化设置 - 最好在演示(视图或视图控制器)级别处理.
如果您将日期存储为字符串,日期组件或日历组件,则会遇到很多问题.例如,如果当前日历已更改,则所有持久数据都将无效,需要重建.夏令时也可能是一个大问题.
在你的情况,你是代表你的模型(秒从范围内的日期范围fromDate至toDate).有一些代表相同事物的替代方式,例如使用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];
Run Code Online (Sandbox Code Playgroud)
这将为您提供当天第8小时的开始和结束fromDate.这只是一个示例,您的业务规则可能会规定更多逻辑,例如检查toDate对fromDate的值等等 - 尽管通过自定义Core Data验证可以最好地处理这些问题中的许多问题.
在谓词中使用它是一组简单的数字比较:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.fromDate <= %@ AND SELF.fromDate >= %@", endOfHour, startOfHour];
Run Code Online (Sandbox Code Playgroud)
当使用NSFetchedResultsController显示部分时,sectionNameKeyPath可以指向核心数据瞬态属性,以允许您根据需要显示基于小时,月等的部分.对查询结果进行排序和分组不能使用瞬态属性,只能使用由建模属性支持的属性 - 在您的情况下,fromDate和toDate.由于日期是数字并代表一个时间点,因此很容易适用于许多业务规则.
| 归档时间: |
|
| 查看次数: |
1602 次 |
| 最近记录: |