Filtering by just time in grails - grails

I'm attempting to create a filter on the view that allows users to filter the data by time ranges:
When users select this, it maps to an enum type TimeRange that contains two date objects. These date objects contain just the respective times, called lowerBound and upperBound respectively. For example:
MIDNIGHT_TO_SIX(1, Date.parse("HH:mm:ss", "00:00:00"), Date.parse("HH:mm:ss", "06:00:00")
This makes a Date object. Because I have not specified the date portion, that is set to epoch date. When I use these in a critieria for filtering:
and {
or {
eq('startDateTime', range.lowerBound)
gt('startDateTime', range.lowerBound)
}
or {
eq('startDateTime', range.upperBound)
lt('startDateTime', range.upperBound)
}
}
Nothing is being returned! This is clearly because none of the dates in my database are before or equal to epoch time, as per the last or closure.
Is there a way of telling the criteria to only use the time portion during the comparison, or is there a way that I can declare lowerBound and upperBound to not be concerned with the Date?

the straight-forward approach would be to save the number of seconds (or millis) from 00:00:00, so that the lookup is as easy as:
enum Range {
MIDNIGHT_TO_SIX( 1, 0, 6 * 60 * 60 ) //in seconds
}
criteria:
{
between 'startInSec', range.lower, range.upper
}

Related

Angular material dateAdapter does not consider different hours/minutes/seconds as a different date

I'm building a time extension (hours/minutes/seconds) for angular material DatePicker (beause there aren't any good ones out there yet). The problem is when I update the time in the time component I use the DatePickers select method which is the only method to set dates programatically using a Date object.
The problem is Datepickers inner select function does not consider different Hours/Minutes/seconds as a different date, and when supplied with such scenarion it will not update its inner workings.
The following is the select function of Angular Material Datepicker:
MatDatepicker.prototype.select = function (date) {
var oldValue = this._selected;
this._selected = date;
// this will eveluate as false since only hours/minuts/seconds are different and not day/month/year
if (!this._dateAdapter.sameDate(oldValue, this._selected)) {
this._selectedChanged.next(date);
}
};
Inside the sameDate method they use a method called compareDate which check the two dates only by day and month & year:
DateAdapter.prototype.compareDate = function (first, second) {
return this.getYear(first) - this.getYear(second) ||
this.getMonth(first) - this.getMonth(second) ||
this.getDate(first) - this.getDate(second);
};
This means select method will not emit the new date to DatePicker's inner components & parts.
I am using a custom NativeDateAdapter and a custom MatDateFormats but since the above check want emit the new date these mechanism want be reached.
P.S
Everything works ok when the updated date has a different day/year/month including the custom time formating to include the time parameters.
I resolved this by simply re-implementing the base classes compareDate method using the custom NativeDateAdapter.
export class AppDateAdapter extends NativeDateAdapter {
format(date: Date, displayFormat: Object): string {
// format your dates
}
compareDate(first: Date, second: Date) {
// compare first/current date with second/previous date
// you can implement your logic here.
return 1;
}
}

Get elements from array where date is today

I have an array of objects where a property is date of type NSDate. The array includes future days and past days.
I want to get an array of elements from that array that only includes dates that are in today, not the last 24 hours.
I ordered the elements by descending (new to old):
allDashboards.sortInPlace({ $0.date!.compare($1.date!) == NSComparisonResult.OrderedDescending
I tried to do a for loop, check if date is yesterday and cut the array there, but it doesn't work as it may be no element with a yesterdays date:
for dash in allDashboards {
if (NSCalendar.currentCalendar().isDateInYesterday(dash.date!)) {
print(i)
allDashboards.removeRange(Range.init(start: 0, end: i))
break
}
i += 1
}
Is there a method to see if date is past a day instead of if the date is part of that day?
One-liner:
let todayDashboards = allDashboards.filter { NSCalendar.currentCalendar().isDateInToday($0.date!) }
You can use NSDateComponents to create the dates which represent the start and end of your acceptable range. These can be anything you want.
Once you have those dates, you can create an NSPredicate which matches dates > the start and < the end dates. This will generate a filtered array for you.
You could use isDateInToday to filter the content too.
What you must not do is to iterate the array and mutate it at the same time, which is what your current code does with allDashboards.removeRange inside the for loop.
You can filter all dates which are today with the filter function and isDateInToday of NSCalendar
let filteredDashboards = allDashboards.filter{ NSCalendar.currentCalendar().isDateInToday($0.date!) }

iOS Swift: Sort array into three dimensional array

I have an array of CKRecords that I would like to sort into a three dimensional array. Within the first array is an array of dates, and each date is an array of names, where a name is an Int between 0 and 4. I'm successfully sorting my records into a two dimensional array currently (code below).
Name can be retrieved with record.objectForKey("Name") as Int
func buildIndex(records: [CKRecord]) -> [[CKRecord]] {
var dates = [NSDate]()
var result = [[[CKRecord]]]()
for record in records {
var date = record.objectForKey("startTime") as NSDate
if !contains(dates, date) {
dates.append(date)
}
}
for date in dates {
var recordForDate = [CKRecord]()
for (index, exercise) in enumerate(records) {
let created = exercise.objectForKey("startTime") as NSDate
if date == created {
let record = records[index] as CKRecord
recordForDate.append(record)
}
}
result.append(recordForDate)
}
return result
}
Not sure the best way to approach this problem. Even general guidance would be appreciated.
General Overview:
Step 1 - choose your sort algorithm. I find that the insertion sort algorithm is the easiest for me to understand and is fast too.
Step 2 - decide on your data structure. You could use a 2-dimensional array. The first dimension represents your dates, and the second dimension represents your records. So the array might be defined like this List<List<CKRecord>>. So the first entry would contain a list (List<CKRecord>) of all the records with the earliest date (it may be one or many).
Basic Steps
(with a 2-D array)
So start with the empty data structure
Figure out which Date list it should go into
If the date does not exist yet, you need to sort the date into the correct position and add a new array/list with the new entry as the only contents
If the date already exists, you need to sort the record into the correct position of the already existing list of records
Enjoy

Swift convert NSTimeInteval to NSDate

I've been following an Objective-C tutorial and the tutor is able to cast an NSTimeInterval object to a NSDate object.
The lesson uses CoreData, and stores the date of a post as an NSTimeInterval, later on we want to retrieve that interval and set it as a formatted date string to present as a section title in a UITableVIewController.
class DiaryEntry: NSManagedObject {
#NSManaged var date: NSTimeInterval
#NSManaged var body: String
#NSManaged var imageData: NSData
#NSManaged var mood: Int16
#NSManaged var location: String
func sectionName() -> String {
let date = NSDate().dateByAddingTimeInterval(self.date)
let f = NSDateFormatter()
f.dateFormat = "MMM yyy"
return f.stringFromDate(date)
}
}
Mainly concerned with the line:
let date:NSDate = NSDate().dateByAddingTimeInterval(self.date)
Which right now is actually adding the set date onto the current date, and this is not the behaviour I want.
How do I cast the self.date variable to an NSDate object in SWIFT?
There is a initializer of NSDate that takes NSTimeInterval:
init(timeIntervalSinceReferenceDate ti: NSTimeInterval)
So just do:
var date = NSDate(timeIntervalSinceReferenceDate: 123)
This code is really confused.
A time interval is not a date. A date is a point in time. A time interval is the difference in seconds between two points in time. Whenever you have a time interval, you have the question "it is the number of seconds between what two dates? You correctly realise that adding a time interval stored in a database to NSDate () is unlikely to give a useful result, because the same call executed 10 seconds later will give a different date.
The date of a post should most likely be stored as an NSDate object. Core Data handles NSDate objects just fine. If you want to store time intervals, the date of the post must be converted to a time interval since some fixed reference date; you do that for example using "timeIntervalSinceReferenceDate". If you do that, I very strongly recommend that you don't call the variable "date" but something like "secondsSinceReferenceDate" which makes it obvious what to store when you are given a date, and how to convert that number back to an NSDate.
(The reason to call it "secondsSinceReferenceDate" is because there is plenty of code that tries to store milliseconds, or nanoseconds, and there is plenty of code that stores intervals since the epoch (Jan 1st 1970), so it's really good if someone reading your code knows immediately what the numbers mean by just looking at the variable name).

Grails Domain Classes Dates

I have this domain class:
class activity {
String name
Date startDate
Date endDate
static constraints = {
}
}
What i want to do is:
a) apply constrains to the dates, for example minimum date and maximum date
b) in my project i need to have an Array of dates and add as many endDates as i want. is it possible to do so? and how
a) apply constrains to the dates, for example minimum date and maximum date
Here's an example of a minimum and maximum constraint applied to the startDate field
class activity {
String name
Date startDate
Date endDate
static constraints = {
// date must be between today and today + 7 days
startDate(min: new Date(), max: newDate() + 7)
}
}
A good reading of the Grails docs would answer a lot of the questions you've been asking here.
a) Adding Custom Validation to a Field
b) If I understand you correctly, what you might want to do is create another class called something like ActivityEndDate and then build your domain like this:
class Activity {
// regular properties
static hasMany = [endDates:ActivityEndDate]
}
Again, the docs are helpful here.

Resources