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 -
I'm working on a problem where I want to do calculations on NSDates where a single NSDate gives different dd/mm/yyyy values in different time zones.
To do that I'm currently using New York City (EST) and Aukland, NZ, since they are frequently on different dates.
I'd like to be able to use the time zones on either side of the international date line, UTC+12, and UTC-12. There appears to be a standard abbreviation for UTC+12, ANAT, for Anadyr, Russia. However, the iOS implementation of TimeZone/NSTimeZone doesn't seem to recognize it. There also does not seem to be an abbreviation for UTC-12 (which would be in Alaska).
Does anybody know if there are such abbreviations for UTC+12 and UTC-12 that iOS (or Mac OS, for that matter) recognizes?
It looks like the answer is no.
I wrote some code to fetch all the system time zones, sort them by offset, and print them:
typealias timeZoneTuple = (abbreviation: String, name: String, offset: Int)
let timeZones = TimeZone.abbreviationDictionary
let mappedTimeZones: [timeZoneTuple] = timeZones
.map {key, value in
var offset = 0
if let timeZone = TimeZone(abbreviation: key) {
offset = timeZone.secondsFromGMT() / 3600
}
return (abbreviation: key, name: value, offset:offset)}
.sorted {$0.offset < $1.offset}
mappedTimeZones.forEach {
let abbreviation = $0.abbreviation.padding(toLength: 4, withPad: " ", startingAt: 0)
let name = $0.name.padding(toLength: 20, withPad: " ", startingAt: 0)
print("abbreviation = \(abbreviation), offset = \(name), val = \($0.offset)")}
The output of the above code is:
abbreviation = HST , offset = Pacific/Honolulu , val = -10
abbreviation = AKDT, offset = America/Juneau , val = -9
abbreviation = AKST, offset = America/Juneau , val = -9
abbreviation = PST , offset = America/Los_Angeles , val = -8
abbreviation = PDT , offset = America/Los_Angeles , val = -8
abbreviation = MDT , offset = America/Denver , val = -7
abbreviation = MST , offset = America/Denver , val = -7
abbreviation = CDT , offset = America/Chicago , val = -6
abbreviation = CST , offset = America/Chicago , val = -6
abbreviation = EDT , offset = America/New_York , val = -5
abbreviation = PET , offset = America/Lima , val = -5
abbreviation = EST , offset = America/New_York , val = -5
abbreviation = COT , offset = America/Bogota , val = -5
abbreviation = ADT , offset = America/Halifax , val = -4
abbreviation = AST , offset = America/Halifax , val = -4
abbreviation = CLT , offset = America/Santiago , val = -3
abbreviation = CLST, offset = America/Santiago , val = -3
abbreviation = ART , offset = America/Argentina/Bu, val = -3
abbreviation = BRST, offset = America/Sao_Paulo , val = -2
abbreviation = BRT , offset = America/Sao_Paulo , val = -2
abbreviation = GMT , offset = GMT , val = 0
abbreviation = WET , offset = Europe/Lisbon , val = 0
abbreviation = BST , offset = Europe/London , val = 0
abbreviation = WEST, offset = Europe/Lisbon , val = 0
abbreviation = UTC , offset = UTC , val = 0
abbreviation = CEST, offset = Europe/Paris , val = 1
abbreviation = WAT , offset = Africa/Lagos , val = 1
abbreviation = CET , offset = Europe/Paris , val = 1
abbreviation = CAT , offset = Africa/Harare , val = 2
abbreviation = MSD , offset = Europe/Moscow , val = 3
abbreviation = EAT , offset = Africa/Addis_Ababa , val = 3
abbreviation = IRST, offset = Asia/Tehran , val = 3
abbreviation = MSK , offset = Europe/Moscow , val = 3
abbreviation = EET , offset = Europe/Istanbul , val = 3
abbreviation = EEST, offset = Europe/Istanbul , val = 3
abbreviation = GST , offset = Asia/Dubai , val = 4
abbreviation = IST , offset = Asia/Calcutta , val = 5
abbreviation = PKT , offset = Asia/Karachi , val = 5
abbreviation = BDT , offset = Asia/Dhaka , val = 6
abbreviation = WIT , offset = Asia/Jakarta , val = 7
abbreviation = ICT , offset = Asia/Bangkok , val = 7
abbreviation = SGT , offset = Asia/Singapore , val = 8
abbreviation = HKT , offset = Asia/Hong_Kong , val = 8
abbreviation = PHT , offset = Asia/Manila , val = 8
abbreviation = KST , offset = Asia/Seoul , val = 9
abbreviation = JST , offset = Asia/Tokyo , val = 9
abbreviation = NZDT, offset = Pacific/Auckland , val = 13
abbreviation = NZST, offset = Pacific/Auckland , val = 13
So it looks like UTC-12, UTC-11, UTC-1, UTC+10, UTC+11, and UTC+12 are all missing from the "named" timezones that are available in Cocoa.
EDIT:
Based on a comment from #MattJohnson, it seems that the identifiers is a better way to get the list of available time zones. Modifying my code to use identifiers instead:
struct timeZoneStruct: CustomStringConvertible {
let identifier: String
var offset: Int
var description: String {
let displayOffset = String(format: "%3d", offset)
let displayIdentifier = (identifier + ",").padding(toLength: 30, withPad: " ", startingAt: 0)
return "identifier = \(displayIdentifier) offset = \(displayOffset)"
}
}
let timeZoneIDs = TimeZone.knownTimeZoneIdentifiers
let mappedTimeZones: [timeZoneStruct] = timeZoneIDs
.map {identifier in
var offset = 0
if let timeZone = TimeZone(identifier: identifier) {
offset = timeZone.secondsFromGMT() / 3600
}
return timeZoneStruct(identifier: identifier, offset: offset)}
.sorted {$0.offset < $1.offset}
mappedTimeZones.forEach {
print($0.description)
}
That yields a list of time zones ranging from UTC-11 (Pacific/Pago_pago) to UTC+14 (Pacific/Apia)
(There are quite a few duplicates for most time zones, so the list is too long to include here.)
So it seems there are defined time zones for offsets from UTC-11 to UTC+14. There is not a time zone for UTC-12 however, even though Baker Island, at Lat/Long: 0°12'N / 176°29'W, is in UTC-12. Curious.
This is the simplest way to get all timezones with their respective abbreviation.
P.S Not all timezones have their proper 3-Letter Abbreviations.
let timezoneList = NSTimeZone.knownTimeZoneNames
for i in 0...timezoneList.count - 1 {
let locale = NSTimeZone.init(name: timezoneList[i])
print("Region: \((locale?.name)!) Abbr: \((locale?.abbreviation)!)")
}
Also total 51, 3-lettered Abbreviations are present:
print(TimeZone.abbreviationDictionary.count)
You can also explore https://developer.apple.com/documentation/foundation/timezone for more.
I have an array of timeStrings of the following format:
x Hr(s) xx min.
I need to add these up to give a total. I'm wondering what is the best way to do this?
My thoughts were to find the index of "Hr(s)". Then if i substring between index 0 and the index of "Hr(s)", I have my hrs var and then add 6 to index of "Hr(s)" and find the index of "min" - 1, to give me the min var.
Then I need to take into account if seconds is greater than 60. So if I divide my seconds var by 60 and the answer is great than 1, I add that answer to my hrs var?
Can anyone see any flaws in this logic?
Sample implementation:
JSON response:
{"status":"OK","hrs":[{"scheduleDate":"2015-11-09","userName":"John Doe","company":"Company X","hrsWorked":"0 Hr(s) 42 min"},{"scheduleDate":"2015-11-10","userName":"Jane Doe","company":"Company Y","hrsWorked":"0 Hr(s) 47 min"},{"scheduleDate":"2015-11-10","userName":"Bob loblaw","company":"Company X","hrsWorked":"0 Hr(s) 37 min"},{"scheduleDate":"2015-11-10","userName":"Joe Soap","company":"Company Y","hrsWorked":"0 Hr(s) 50 min"},{"scheduleDate":"2015-11-10","userName":"Test","company":"Company Y","hrsWorked":"0 Hr(s) 40 min"}],"queryStatus":"OK","message":null,"count":5}
var hrsVar = 0
var minsVar = 0
loop through hrsArray{
hrsMinStr = hrsWorkedInJson
if let endHrsIndex = hrsMinStr.lowercaseString.characters.indexOf("Hr(s)") {
print("Index: \(index)")
let hrsStr = Int(hrsMinStr.substringWithRange(Range<String.Index>(start: 0, end: endHrsIndex)))
hrsVar += hrsStr
let minStr = Int(hrsMinStr.substringWithRange(Range<String.Index>(start: endHrsIndex + 1, end: hrsMinStr.length - 3)))
minsVar += minStr
}
}
if minsVar/60 > 1 {
hrsVar = hrsVar + minsVar/60
minsVar = minsVar%60
}
Update
It seems as though I cannot pass in "Hr(s)" and instead only a single character "h". Because of this, I was trying to use the advancedBy(x) method to get the right endIndex. But I'm getting the error:
Cannot invoke initializer for type 'Range<Index>' with an argument list of type '(start: Int, end: String.CharacterView.Index)'
Updated code:
if let endHrsIndex = hrsMinStr.lowercaseString.characters.indexOf("h") {
print("Index: \(endHrsIndex)")
let hrsStr = Int(hrsMinStr.substringWithRange(Range<String.Index>(start: 0, end: endHrsIndex)))
hrsVar += hrsStr
let minStr = Int(hrsMinStr.substringWithRange(Range<String.Index>(start: endHrsIndex.advancedBy(5), end: hrsMinStr.length.characters.count.advancedBy(-3))))
minsVar += minStr
}
I'm really looking for the most efficient approach as possible, so please advise if there is a better way/if you see issues with this approach
import Foundation
let str = "0 Hr(s) 42 min"
let time = str
.stringByReplacingOccurrencesOfString("Hr(s)", withString:":")
.stringByReplacingOccurrencesOfString("min", withString: "")
.stringByReplacingOccurrencesOfString(" ", withString: "")
let t = time.characters.split(Character(":"))
let h = Int(String(t[0])) // 0
let m = Int(String(t[1])) // 1
and sum
import Foundation
var time: [(hours:Int,minutes:Int,seconds:Int)] = []
for i in 0...5 {
let h = Int(arc4random_uniform(24))
let m = Int(arc4random_uniform(60))
let s = Int(arc4random_uniform(60))
time.append((h,m,s))
}
let t = time.reduce(0) { (sum, time: (hours: Int, minutes: Int, seconds: Int)) -> Int in
sum + time.seconds + time.minutes * 60 + time.hours * 60 * 60
}
let seconds = t % 60
let minutes = ((t - seconds) / 60) % 60
let hours = ((t - seconds) / 3660)
time.forEach {
print(String(format: " %6d:%02d:%02d", arguments: [$0.hours,$0.minutes, $0.seconds]))
}
print("-------------------")
print(String(format: "Sum: %6d:%02d:%02d", arguments: [hours,minutes,seconds]))
/*
12:25:04
2:43:36
14:09:35
11:59:43
10:39:19
23:32:14
-------------------
Sum: 74:29:31
*/
You should most likely try using the scanners in your case.
let string = "12 Hr(s) 37 min"
let scanner = NSScanner(string: string)
var min: Int = 0
var hour : Int = 0
scanner.scanInteger(&hour)
scanner.scanString("Hr(s) ", intoString: nil)
scanner.scanInteger(&min)
Or even easier if you create this part in Objective-C:
int min, hour;
sscanf("12 Hr(s) 37 min", "%d Hr(s) %d min", &hour, &min);
What is wrong with this code in swift accessing the time and date functions in C? The date it gives me is off by 3 days even though the difftime function is correct on the time difference.
import Darwin
var time1 = tm(tm_sec: 00, tm_min: 00, tm_hour: 00, tm_mday: 13, tm_mon: 06, tm_year: 1977, tm_wday: 0, tm_yday: 0, tm_isdst: 0, tm_gmtoff: 0, tm_zone: nil)
var time1secs = timegm(&time1)
var time2secs = timegm(&time1) + 1_000_000_000
var time2 = gmtime(&time2secs).memory
difftime(time2secs, time1secs) // 1,000,000,000
print("\(time2.tm_year)-\(time2.tm_mon)-\(time2.tm_mday)") //2009-2-22
// The correct answer is 2009-02-19
In the struct tm, the tm_year field is the number of years
since 1900, and tm_mon is the month in the range 0 .. 11:
// struct tm for 1977/06/13:
var time1 = tm()
time1.tm_year = 1977 - 1900
time1.tm_mon = 06 - 1
time1.tm_mday = 13
// Add 10^9 seconds:
var time2secs = timegm(&time1) + 1_000_000_000
var time2 = gmtime(&time2secs).memory
// Extract year/month/day:
let year = time2.tm_year + 1900
let month = time2.tm_mon + 1
let day = time2.tm_mday
print("\(year)-\(month)-\(day)") // 2009-2-19
Look at this code:
var timepenalty = UInt8(0)
var currentTime = NSDate.timeIntervalSinceReferenceDate()
// Find the difference between current time and start time
var elapsedTime: NSTimeInterval = currentTime - startTime
let adjustedTime = UInt8(timepenalty + elapsedTime)
error-
"Could not find an overload for "+" that accepts the requested arguments.
"
This is for a game that adds time to the stopwatch-style timer, every time the player makes a mistake. The code works when I just use an integer instead of the elapsedTime variable as so:
let adjustedTime = UInt8(elapsedTime + 5)
but replacing 5 with a variable gives an error.
Here's the full code for the updateTime function:
func updateTime() {
var currentTime = NSDate.timeIntervalSinceReferenceDate()
// Find the difference between current time and start time
var elapsedTime: NSTimeInterval = currentTime - startTime
let adjustedTime = UInt8(timepenalty + elapsedTime)
// calculate the minutes in elapsed time
let minutes = UInt8(elapsedTime / 60.0)
elapsedTime -= (NSTimeInterval(minutes) * 60)
// calculate the seconds in elapsed time
seconds = UInt8(elapsedTime)
elapsedTime -= NSTimeInterval(seconds)
// seconds += timepenalty
// find out the fraction of millisends to be displayed
let fraction = UInt8(elapsedTime * 100)
// if seconds > 20 {
// exceedMsgLabel.text = "超过20秒了"
// }
// add the leading zero for minutes, seconds and millseconds and store them as string constants
let startMinutes = minutes > 9 ? String(minutes):"0" + String(minutes)
let startSeconds = seconds > 9 ? String(seconds):"0" + String(seconds)
let startFraction = fraction > 9 ? String(fraction):"0" + String(fraction)
displayTimeLabel.text = "\(startMinutes):\(startSeconds):\(startFraction)"
var penalty = String(timepenalty)
penaltylabel.text = "+ " + penalty
}
#David's code is good, but I'd strongly recommend that you make adjustedTime be an NSTimeInterval. It is a time interval, and that's what the type is for. Then all your casting issues go away.
The UInt8 type is reserved for cases where you explicitly need an 8-bit bit-pattern (like for networking protocols or binary file formats). It isn't intended for "small numbers." Moving between signed and unsigned numbers and different sized-numbers are common sources of bugs, and is intentionally made cumbersome.
If you do need to force a Double to be a whole number, just use Int rather than UInt8 in most cases. In most of these cases it looks like you really mean floor() rather than Int() anyway. You're just normalizing to an whole number.
That said, a more typical way to do your formatting is:
import Foundation
let totalSeconds: NSTimeInterval = 100.51
let frac = Int((totalSeconds - floor(totalSeconds)) * 100)
let seconds = Int(totalSeconds % 60)
let minutes = Int((totalSeconds / 60) % 60)
let result = String(format: "%02d:%02d:%02d", minutes, seconds, frac)
This line:
let adjustedTime = UInt8(timepenalty + elapsedTime)
is attempting to add a UInt8 (time penalty) and an NSTimeInterval (double, elapsedTime) which fails as there is no implicit type conversion in Swift. Change it to:
let adjustedTime = timepenalty + UInt8(elapsedTime)
Which converts the NSTimeInterval to a UInt8 before the addition.
UInt8 and NSTimeInterval are two different types. You need to make each operand the same type. (Or you could use operator overloading.)