Core Plot CPTAxisLabelingPolicyAutomatic Days only - ios

I'm using CPTAxisLabelingPolicyAutomatic on my x-axis which for time-line for days of a year (e.g. 07 March 2015).
This is my reference date:
let components = NSDateComponents()
components.month = 10
components.day = 29
components.year = 1970
components.hour = 0
components.minute = 0
components.second = 0
referenceDate = NSCalendar.currentCalendar().dateFromComponents(components)!
and here is part of my x axis style
x.labelingPolicy = .Automatic
let oneDay:NSTimeInterval = 60 * 60 * 24
x.majorIntervalLength = oneDay
x.minorTicksPerInterval = 0
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
formatter.timeStyle = .NoStyle
let timeFormatter = CPTTimeFormatter(dateFormatter: formatter)
timeFormatter.referenceDate = referenceDate
x.labelFormatter = timeFormatter
The problem is eventhough, the x values are NSDate at 00:00:00 of the days they do not stick to the gridline for that specific date:
but if I use .FixedInterval policy I get the correct behaviour but I loose the autmatic labeling on pinching.
How can I benefit from the two world?

The automatic labeling algorithm doesn't know about dates, so it won't split the axis into "nice" date intervals like days or weeks. Right now, the fixed interval labeling policy is the best solution. It is up to you to determine the proper interval based on the range being displayed. There is an open issue to add proper date support, but it's pretty low priority and I can't guarantee when it will be done.

Related

Set tickInterval in format HH:mm am/pm of a HIChart's Line chart using Swift 5.0

I want to set intervals as per the below image. I have tried to set using it below code.
let xAxis = HIXAxis()
xAxis.type = "datetime"
xAxis.dateTimeLabelFormats = HIDateTimeLabelFormats()
xAxis.dateTimeLabelFormats.day = HIDay()
xAxis.dateTimeLabelFormats.day.main = "%l:%M"
xAxis.min = NSNumber(value: ConverteddateFrom ) //Millisecond 12 AM midnight from starting of the day
xAxis.max = NSNumber(value: ConverteddateEnd) //Millisecond 12 AM to end of the day
xAxis.tickInterval = NSNumber(value: 4 * 3600 * 1000 )
xAxis.categories = DateList
options.xAxis = [xAxis]
let plotoptions = HIPlotOptions()
plotoptions.series = HISeries()
plotoptions.series.label = HILabel()
plotoptions.series.label.connectorAllowed = NSNumber(value: false)
// plotoptions.series.pointStart = 12
// plotoptions.series.pointInterval = NSNumber(value: 4)
// plotoptions.series.pointIntervalUnit = "AM"
options.plotOptions = plotoptions
let line1 = HILine()
line1.name = "Phase B"
line1.data = PhaseBList
let line2 = HILine()
line2.name = "Phase R"
line2.data = PhaseRList
let line3 = HILine()
line3.name = "Phase Y"
line3.data = PhaseYList
options.series = [line1, line2, line3]
options.responsive = responsive
options.colors = ["#7CB5EC","#F94F6C", "#FFB647"]
inputVoltage.options = options
but I didn't get proper x-axis with intervals. can anybody help me on this?
I am getting on x-axis points something like starting point as 20:00 to 16:00 with interval of 4 hours. I am expecting it from 12Am to 12Am. Also I can't see the data on graph.
You have 4 hour tick interval, so probably you need to change dateTimeLabelFormats from day to hour:
xAxis.dateTimeLabelFormats = HIDateTimeLabelFormats()
xAxis.dateTimeLabelFormats.hour = HIHour()
xAxis.dateTimeLabelFormats.hour.main = "%l %P"
xAxis.dateTimeLabelFormats.day = HIDay()
xAxis.dateTimeLabelFormats.day.main = "%l %P"
API Reference: https://api.highcharts.com/ios/highcharts/
I have got the solution -
1 - The problem was with the data presenting. Initially I was added the data array only whereas we have to add data along with its correspondence date. So it becomes array of array like this -
line1.data = [
[1562106600000, 0],
[1562121000000, 0.25]
]
2 - x axis time from 20:00 to 16:00 is because of UTC time. Solution is :
options.time = HITime()
options.time.useUTC = false
//options.time.timezone = "Asia/Kolkata" // If you want to set timezon you can
3 - converting the date into AM/PM in 12 hrs format.
xAxis.type = "datetime"
xAxis.dateTimeLabelFormats = HIDateTimeLabelFormats()
xAxis.dateTimeLabelFormats.hour = HIHour()
xAxis.dateTimeLabelFormats.hour.main = "%l %P"
xAxis.dateTimeLabelFormats.day = HIDay()
xAxis.dateTimeLabelFormats.day.main = "%l %P"
xAxis.min = NSNumber(value: ConverteddateFrom ) //Millisecond 12 AM midnight from starting of the day
xAxis.max = NSNumber(value: ConverteddateEnd) //Millisecond 12 AM midnight from ending of the day
xAxis.tickInterval = NSNumber(value: 4 * 3600 * 1000 )
options.xAxis = [xAxis]
This is how my graph is looking now -

Swift - Timezone off by one hour / secondsFromGMT incorrect

This should be a really simple question but I just can't seem to wrap my head around it.
Given my timezone is EDT (GMT-4), why does 04:00 in GMT turn into 23:00 and not 00:00?
// The offset is -4 hours
let offsetFromGMT = Calendar.current.timeZone.secondsFromGMT() / 60 / 60
// 2017-03-12 04:00
var destinationComponents = DateComponents()
destinationComponents.timeZone = TimeZone(secondsFromGMT: 0)
destinationComponents.year = 2017
destinationComponents.month = 03
destinationComponents.day = 12
destinationComponents.hour = -offsetFromGMT // 4 hours
// Why is this 2017-03-11 23:00 and not 2017-03-12 00:00?
let date = Calendar.current.date(from: destinationComponents)!
// Outputs 23
Calendar.current.dateComponents([.hour], from: date).hour
Calendar.current.timeZone.secondsFromGMT()
is the current GMT offset for your time zone. In your case that
is 4 hours, because the current time zone in New York is EDT = GMT-4,
with daylight saving time active.
So your destinationComponents and date are four o'clock in
the morning Greenwich time:
2017-03-12 04:00:00 +0000
At that point, the time zone in New York was EST = GMT-5, and
daylight saving time not active. Therefore that date is 2017-03-11 23:00 in your local time zone.
I would proceed differently, avoiding "secondsFromGMT".
Example: "2017-03-12 00:00:00" New York time is "2017-03-12 05:00:00" GMT.
var srcComponents = DateComponents()
srcComponents.timeZone = TimeZone(identifier: "America/New_York")!
srcComponents.year = 2017
srcComponents.month = 3
srcComponents.day = 12
srcComponents.hour = 0
srcComponents.minute = 0
let date = Calendar.current.date(from: srcComponents)!
print(date) // 2017-03-12 05:00:00 +0000

NSDateComponentsFormatter not supported large interval

let date = NSDate()
let future = NSDate.distantFuture()
let f = NSDateComponentsFormatter()
f.unitsStyle = .Full
f.allowedUnits = [.Year, .Month, .Day]
f.stringFromTimeInterval(future.timeIntervalSinceDate(date))
Result is "-57 years, 0 months, 26 days" which is wrong.
I thought this might cause from overflow, so I try smaller number and found that this weird behavior start at 69 years interval
let date = NSDate()
let sixtyEightYears = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: 68, toDate: date, options: NSCalendarOptions())!
let sixtyNineYears = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: 69, toDate: date, options: NSCalendarOptions())!
let f = NSDateComponentsFormatter()
f.unitsStyle = .Full
f.allowedUnits = [.Year, .Month, .Day]
future.timeIntervalSinceDate(date)
sixtyEightYears.timeIntervalSinceDate(date) // 2145916800
sixtyNineYears.timeIntervalSinceDate(date) // 2177452800
f.stringFromTimeInterval(sixtyNineYears.timeIntervalSinceDate(date)) // "-67 years, 1 month, 6 days"
Is this the Apple bug, or I did something wrong?
The method timeIntervalSinceDate whose reference date is 1 January 1970 causes the problem.
1970 + 68 = 2038
From Wikipedia:
Year 2038 problem
The Year 2038 problem is an issue for computing and data storage
situations in which time values are stored or calculated as a signed
32-bit integer, and this number is interpreted as the number of
seconds since 00:00:00 UTC on 1 January 1970 ("the epoch"). Such
implementations cannot encode times after 03:14:07 UTC on 19 January
2038, a problem similar to but not entirely analogous to the "Y2K
problem" (also known as the "Millennium Bug"), in which 2-digit values
representing the number of years since 1900 could not encode the year
2000 or later. Most 32-bit Unix-like systems store and manipulate time
in this "Unix time" format, so the year 2038 problem is sometimes
referred to as the "Unix Millennium Bug" by association.
Full article : Year 2038 problem

How to get year month day from NSDate for the current timezone

I am current at timezone UTC-05:00. When I call the function NSDate(timeIntervalSince1970:0), it returns back "Dec 31, 1969, 7:00 PM"
let date = NSDate.init(timeIntervalSince1970: 0) // "Dec 31, 1969, 7:00 PM"
print(date) // "1970-01-01 00:00:00 +0000\n"
I read about this How to get NSDate day, month and year in integer format? But the problem is that with the following, I always get 1969-12-31 because of the 5 hour time difference.
let calendar = NSCalendar.currentCalendar()
calendar.getEra(&era, year:&year, month:&month, day:&day, fromDate: date)
year // 1969
month // 12
day // 31
var hour = 0, minute = 0, second = 0
calendar.getHour(&hour, minute: &minute, second: &second, nanosecond: nil, fromDate: date)
hour // 19
minute // 0
second // 0
Is there a way to get the current year, month, day values and etc. in the current timezone. What I am looking for here is:
year // 1970
month // 01
day // 01
The timeIntervalSince1970 initializer gives you (as documented) an NSDate which is some number of seconds since Jan 1 1970 at 00:00:00 in UTC, not in your local time zone. Those results you're getting are correct, because they're showing your local time zone's offset from that time. You're passing in 0, so you're getting Jan 1 1970 at 00:00:00 UTC, and then NSCalendar is giving you the equivalent date and time in your local time zone.
If you want to get Jan 1 1970 at 00:00:00 in your local time zone, you need to request that date specifically from NSCalendar:
let calendar = NSCalendar.currentCalendar()
calendar.timeZone = NSTimeZone.localTimeZone()
let date = calendar.dateWithEra(1, year: 1970, month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)
calendar.getEra(&era, year:&year, month:&month, day:&day, fromDate: date!)
year // 1970
month // 1
day // 1
This is not a 0 offset for timeIntervalSince1970. If you check, you'll see that the result corresponds to your time zone's offset from UTC:
date?.timeIntervalSince1970 // 25200, for me
This will return the current date ex. 02/26/2016
// Format date so we may read it normally
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd/M/yyyy"
let currentDate = String(dateFormatter.stringFromDate(NSDate()))
Swift 3.0
NSDateFormatter > DateFormatter && NSDate > Date
let df = DateFormatter()
df.timeZone = .current
df.dateStyle = .medium
df.timeStyle = .short
df.dateFormat = "dd/M/yyyy"
let currentDate = df.string(from: Date())

how to query by date offset in Parse with Swift?

I want to set a constraint on a Parse query, that takes a birthday ( date), and only gathers results which are within 10 years.
So if the date is something like (1954-01-10 07:00:00 +0000)
then I want to get all records from 1944 to 1964.
Is there some way to do this using Parse query code?
Or,
do I have to obtain the date, then use swift code to offset it by 10 years, then write something like this
let currentUserBirthday = PFUser.currentUser()?.objectForKey("birthday")!
// set date 10 years greater and lower than currentUserBirthday
let datePlus10 = // add 10 years to date
let dateMinus10 = // subtract 10 years from date
dailyFourQuery?.whereKey("birthday", greaterThanOrEqualTo: datePlus10)
dailyFourQuery?.whereKey("birthday", lessThanOrEqualTo: dateMinus10)
edit: hey guys, i solved this by getting the age from the date, then adding or subtracting the integer offset from that number,
then using NSCalendar and creating components with modified values.
Thanks for all the help.
let currentUserBirthdayNSDate = currentUserBirthday as! NSDate
let dateComponents = calendar.components([NSCalendarUnit.Day, NSCalendarUnit.Month, NSCalendarUnit.Year, NSCalendarUnit.WeekOfYear, NSCalendarUnit.Hour, NSCalendarUnit.Minute, NSCalendarUnit.Second, NSCalendarUnit.Nanosecond], fromDate: currentUserBirthdayNSDate)
let componentsPlus10 = NSDateComponents()
componentsPlus10.day = dateComponents.day
componentsPlus10.month = dateComponents.month
componentsPlus10.year = dateComponents.year + 10
componentsPlus10.hour = dateComponents.hour
componentsPlus10.minute = dateComponents.minute
You can refer to SwiftDate
// Reference date is: Thu, 19 Nov 2015 19:00:00 UTC (1447959600 from 1970)
let refDate = NSDate(timeIntervalSince1970: 1447959600)
// Remember: all parameters are optional; in this example we have ignored minutes and seconds
let newDate = refDate.add(years: 1, months: 2, days: 1, hours: 2)
// newdate is 2017-01-21 14:00:00 +0000
// This is equivalent to
let newDate2 = refDate + 1.years + 2.months + 1.days + 2.hours
do you want this?

Resources