Not able to view the last label in xaxis - highcharts
We are creating a line chart for which we are facing some issues. xaxis title is not getting populated for some last values, and this is plotted in the chart, but not been displayed in the label part. Please do help us in providing some solution for it.
Have the issue here :
http://jsfiddle.net/58jy1zhd/1/
$(function () {
$('#container').highcharts({
xAxis: {
categories: ["20-04-2015, 6:55 PM","20-04-2015, 7:00 PM","20-04-2015, 7:05 PM","20-04-2015, 7:10 PM","20-04-2015, 7:15 PM","20-04-2015, 7:20 PM","20-04-2015, 7:25 PM","20-04-2015, 7:30 PM","20-04-2015, 7:35 PM","20-04-2015, 7:40 PM","20-04-2015, 7:45 PM","20-04-2015, 7:50 PM","20-04-2015, 7:55 PM","20-04-2015, 8:00 PM","20-04-2015, 8:05 PM","20-04-2015, 8:10 PM","20-04-2015, 8:15 PM","20-04-2015, 8:20 PM","20-04-2015, 8:25 PM","20-04-2015, 8:30 PM","20-04-2015, 8:35 PM","20-04-2015, 8:40 PM","20-04-2015, 8:45 PM","20-04-2015, 8:50 PM","20-04-2015, 8:55 PM","20-04-2015, 9:00 PM","20-04-2015, 9:05 PM","20-04-2015, 9:10 PM","20-04-2015, 9:15 PM","20-04-2015, 9:20 PM","20-04-2015, 9:25 PM","20-04-2015, 9:30 PM","20-04-2015, 9:35 PM","20-04-2015, 9:40 PM","20-04-2015, 9:45 PM","20-04-2015, 9:50 PM","20-04-2015, 9:55 PM","20-04-2015, 10:00 PM","20-04-2015, 10:05 PM","20-04-2015, 10:10 PM","20-04-2015, 10:15 PM","20-04-2015, 10:20 PM","20-04-2015, 10:25 PM","20-04-2015, 10:30 PM","20-04-2015, 10:35 PM","20-04-2015, 10:40 PM","20-04-2015, 10:45 PM","20-04-2015, 10:50 PM","20-04-2015, 10:55 PM","20-04-2015, 11:00 PM","20-04-2015, 11:05 PM","20-04-2015, 11:10 PM","20-04-2015, 11:15 PM","20-04-2015, 11:20 PM","20-04-2015, 11:25 PM","20-04-2015, 11:30 PM","20-04-2015, 11:35 PM","20-04-2015, 11:40 PM","20-04-2015, 11:45 PM","20-04-2015, 11:50 PM","20-04-2015, 11:55 PM","21-04-2015, 12:00 AM","21-04-2015, 12:05 AM","21-04-2015, 12:10 AM","21-04-2015, 12:15 AM","21-04-2015, 12:20 AM","21-04-2015, 12:25 AM","21-04-2015, 12:30 AM","21-04-2015, 12:35 AM","21-04-2015, 12:40 AM","21-04-2015, 12:45 AM","21-04-2015, 12:50 AM","21-04-2015, 12:55 AM","21-04-2015, 1:00 AM","21-04-2015, 1:05 AM","21-04-2015, 1:10 AM","21-04-2015, 1:15 AM","21-04-2015, 1:20 AM","21-04-2015, 1:25 AM","21-04-2015, 1:30 AM","21-04-2015, 1:35 AM","21-04-2015, 1:40 AM","21-04-2015, 1:45 AM","21-04-2015, 1:50 AM","21-04-2015, 1:55 AM","21-04-2015, 2:00 AM","21-04-2015, 2:05 AM","21-04-2015, 2:10 AM","21-04-2015, 2:15 AM","21-04-2015, 2:20 AM","21-04-2015, 2:25 AM","21-04-2015, 2:30 AM","21-04-2015, 2:35 AM","21-04-2015, 2:40 AM","21-04-2015, 2:45 AM","21-04-2015, 2:50 AM","21-04-2015, 2:55 AM","21-04-2015, 3:00 AM","21-04-2015, 3:05 AM","21-04-2015, 3:10 AM","21-04-2015, 3:15 AM","21-04-2015, 3:20 AM","21-04-2015, 3:25 AM","21-04-2015, 3:30 AM","21-04-2015, 3:35 AM","21-04-2015, 3:40 AM","21-04-2015, 3:45 AM","21-04-2015, 3:50 AM","21-04-2015, 3:55 AM","21-04-2015, 4:00 AM","21-04-2015, 4:05 AM","21-04-2015, 4:10 AM","21-04-2015, 4:15 AM","21-04-2015, 4:20 AM","21-04-2015, 4:25 AM","21-04-2015, 4:30 AM","21-04-2015, 4:35 AM","21-04-2015, 4:40 AM","21-04-2015, 4:45 AM","21-04-2015, 4:50 AM","21-04-2015, 4:55 AM","21-04-2015, 5:00 AM","21-04-2015, 5:05 AM","21-04-2015, 5:10 AM","21-04-2015, 5:15 AM","21-04-2015, 5:20 AM","21-04-2015, 5:25 AM","21-04-2015, 5:30 AM","21-04-2015, 5:35 AM","21-04-2015, 5:40 AM","21-04-2015, 5:45 AM","21-04-2015, 5:50 AM","21-04-2015, 5:55 AM","21-04-2015, 6:00 AM","21-04-2015, 6:05 AM","21-04-2015, 6:10 AM","21-04-2015, 6:15 AM","21-04-2015, 6:20 AM","21-04-2015, 6:25 AM","21-04-2015, 6:30 AM","21-04-2015, 6:35 AM","21-04-2015, 6:40 AM","21-04-2015, 6:45 AM","21-04-2015, 6:50 AM","21-04-2015, 6:55 AM","21-04-2015, 7:00 AM","21-04-2015, 7:05 AM","21-04-2015, 7:10 AM","21-04-2015, 7:15 AM","21-04-2015, 7:20 AM","21-04-2015, 7:25 AM","21-04-2015, 7:30 AM","21-04-2015, 7:35 AM","21-04-2015, 7:40 AM","21-04-2015, 7:45 AM","21-04-2015, 7:50 AM","21-04-2015, 7:55 AM","21-04-2015, 8:00 AM","21-04-2015, 8:05 AM","21-04-2015, 8:10 AM","21-04-2015, 8:15 AM","21-04-2015, 8:20 AM","21-04-2015, 8:25 AM","21-04-2015, 8:30 AM","21-04-2015, 8:35 AM","21-04-2015, 8:40 AM","21-04-2015, 8:45 AM","21-04-2015, 8:50 AM","21-04-2015, 8:55 AM","21-04-2015, 9:00 AM","21-04-2015, 9:05 AM","21-04-2015, 9:10 AM","21-04-2015, 9:15 AM","21-04-2015, 9:20 AM","21-04-2015, 9:25 AM","21-04-2015, 9:30 AM","21-04-2015, 9:35 AM","21-04-2015, 9:40 AM","21-04-2015, 9:45 AM","21-04-2015, 9:50 AM","21-04-2015, 9:55 AM","21-04-2015, 10:00 AM","21-04-2015, 10:05 AM","21-04-2015, 10:10 AM","21-04-2015, 10:15 AM","21-04-2015, 10:20 AM","21-04-2015, 10:25 AM","21-04-2015, 10:30 AM","21-04-2015, 10:35 AM","21-04-2015, 10:40 AM","21-04-2015, 10:45 AM","21-04-2015, 10:50 AM","21-04-2015, 10:55 AM","21-04-2015, 11:00 AM","21-04-2015, 11:05 AM","21-04-2015, 11:10 AM","21-04-2015, 11:15 AM","21-04-2015, 11:20 AM","21-04-2015, 11:25 AM","21-04-2015, 11:30 AM","21-04-2015, 11:35 AM","21-04-2015, 11:40 AM","21-04-2015, 11:45 AM","21-04-2015, 11:50 AM","21-04-2015, 11:55 AM","21-04-2015, 12:00 PM","21-04-2015, 12:05 PM","21-04-2015, 12:10 PM","21-04-2015, 12:15 PM","21-04-2015, 12:20 PM","21-04-2015, 12:25 PM","21-04-2015, 12:30 PM","21-04-2015, 12:35 PM","21-04-2015, 12:40 PM","21-04-2015, 12:45 PM","21-04-2015, 12:50 PM","21-04-2015, 12:55 PM","21-04-2015, 1:00 PM","21-04-2015, 1:05 PM","21-04-2015, 1:10 PM","21-04-2015, 1:15 PM","21-04-2015, 1:20 PM","21-04-2015, 1:25 PM","21-04-2015, 1:30 PM","21-04-2015, 1:35 PM","21-04-2015, 1:40 PM","21-04-2015, 1:45 PM","21-04-2015, 1:50 PM","21-04-2015, 1:55 PM","21-04-2015, 2:00 PM","21-04-2015, 2:05 PM","21-04-2015, 2:10 PM","21-04-2015, 2:15 PM","21-04-2015, 2:20 PM","21-04-2015, 2:25 PM","21-04-2015, 2:30 PM","21-04-2015, 2:35 PM","21-04-2015, 2:40 PM","21-04-2015, 2:45 PM","21-04-2015, 2:50 PM","21-04-2015, 2:55 PM"],
title: {
text: 'Time'
},
labels: {
rotation: -90,
},
showLastLabel: true,
endOnTick: true
},
series: [{
name: 'TEST',
data: [124.22,125.67,127.12,122.77,122.77,121.33,121.33,119.89,122.77,122.77,124.22,121.33,122.77,124.22,121.33,119.89,119.89,119.89,122.77,119.89,118.46,118.46,119.89,119.89,122.77,121.33,121.33,121.33,122.77,121.33,122.77,121.33,121.33,124.22,119.89,119.89,121.33,121.33,122.77,119.89,118.46,118.46,119.89,117.03,118.46,117.03,119.89,117.03,117.03,118.46,118.46,121.33,121.33,122.77,122.77,121.33,125.67,124.22,127.12,125.67,124.22,128.58,125.67,127.12,122.77,127.12,121.33,121.33,115.6,111.35,112.76,105.74,107.14,107.14,104.35,100.2,98.83,101.58,100.2,97.45,97.45,96.09,94.72,93.36,93.36,94.72,96.09,93.36,93.36,92.01,93.36,92.01,92.01,92.01,94.72,92.01,89.31,89.31,90.66,92.01,87.97,87.97,89.31,87.97,90.66,89.31,89.31,90.66,89.31,90.66,92.01,90.66,86.63,87.97,89.31,89.31,86.63,89.31,87.97,87.97,86.63,86.63,87.97,85.29,87.97,87.97,87.97,87.97,86.63,87.97,86.63,87.97,85.29,86.63,86.63,85.29,86.63,85.29,86.63,87.97,86.63,86.63,85.29,85.29,85.29,83.96,85.29,85.29,83.96,83.96,83.96,83.96,83.96,83.96,83.96,83.96,83.96,83.96,83.96,82.63,83.96,82.63,81.31,82.63,83.96,82.63,82.63,82.63,79.98,81.31,81.31,82.63,82.63,81.31,81.31,81.31,81.31,81.31,82.63,81.31,81.31,79.98,79.98,79.98,81.31,79.98,79.98,79.98,79.98,79.98,79.98,79.98,79.98,79.98,78.67,79.98,79.98,78.67,78.67,79.98,78.67,82.63,79.98,78.67,79.98,78.67,78.67,77.35,78.67,77.35,78.67,78.67,78.67,79.98,83.96,90.66,92.01,94.72,97.45,100.2,102.96,105.74,101.58,98.83,96.09,94.72,93.36,92.01,89.31,90.66,89.31,86.63,85.29,86.63,85.29,85.29,85.29,82.63,83.96,82.63,82.63]
}]
});
});
The chart in this URL shows the last xaxis value as 243 instead of "21-04-2015, 2:55 PM" value, which is the last in the series.
Have tried with :
showLastLabel: true,
endOnTick: true
but no luck.
Thanks in advance, Naveen.
This is happening because you have too many labels you're trying to display on the axis. It is only showing every third label right now, and the way it ends, the last two categories are not in the loop.
There are two things you can do.
1) reduce your font size for the labels, and take a look at the step and tickInterval properties.
Example:
http://jsfiddle.net/jlbriggs/58jy1zhd/4/
But really, that's just kind of silly. That's way too many labels to make sense of, and it uses a full half of the visual real estate to display them, and has to display them sideways, making it even harder to make sense of.
So I recommend 2) use a date time axis. You have all of the date information. You can either pass those dates as the x values of your data, or, if they're always going to be uniform (ie the same distance apart), as they appear to be already, you can use the pointStart and pointInterval properties.
Example:
http://jsfiddle.net/jlbriggs/58jy1zhd/3/
It doesn't show every label. But it's pretty futile, and ultimately useless to try showing every label of a time series.
You can manipulate the axis to make sure it shows the first and last, and you can format the label output to include the date portion, or any other thing that you want it to.
[[edit to add label formatting reference links:
http://api.highcharts.com/highcharts#xAxis.labels.formatter
http://api.highcharts.com/highcharts#xAxis.labels.format
http://api.highcharts.com/highcharts#xAxis.dateTimeLabelFormats
Example using the formatter function to display date and time for each tick, with a tick every 4 hours:
http://jsfiddle.net/58jy1zhd/7/
Related
How to use DateComponents to represent the extra 1 hour period at the end of day light saving?
Usually, during end of day light saving, we will be gaining extra 1 hours. Take Tehran timezone as an example. During 22 September 2021, Tehran will backward by 1 hour from 00:00 AM, to 11:00 PM. I wrote the following code to demonstrate such. import UIKit func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) -> Date { var dateComponents = DateComponents() dateComponents.year = year dateComponents.month = month dateComponents.day = day dateComponents.hour = hour dateComponents.minute = minute dateComponents.second = second let date = Calendar.current.date(from: dateComponents)! return date } // During 22 September 2021, Tehran will backward by 1 hour from 00:00 AM, to 11:00 PM. let tehranTimeZone = TimeZone(identifier: "Asia/Tehran")! let oldDefault = NSTimeZone.default NSTimeZone.default = tehranTimeZone defer { NSTimeZone.default = oldDefault } let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59) let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00) let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01) // STEP 1: 2021 Sep 21 23:59:59 => 1632252599.0, Tuesday, September 21, 2021 at 11:59:59 PM Iran Daylight Time print("STEP 1: 2021 Sep 21 23:59:59 => \(date1.timeIntervalSince1970), \(date1.description(with: .current))") // STEP 2: 2021 Sep 22 00:00:00 => 1632256200.0, Wednesday, September 22, 2021 at 12:00:00 AM Iran Standard Time print("STEP 2: 2021 Sep 22 00:00:00 => \(date2.timeIntervalSince1970), \(date2.description(with: .current))") // STEP 3: 2021 Sep 22 00:00:01 => 1632256201.0, Wednesday, September 22, 2021 at 12:00:01 AM Iran Standard Time print("STEP 3: 2021 Sep 22 00:00:01 => \(date3.timeIntervalSince1970), \(date3.description(with: .current))") From STEP 1 transits to STEP 2, instead for their timeIntervalSince1970 different by +1 seconds, their difference are +3601 seconds, due to the extra 1 hour gain. Now, my question is, how can we use DateComponents to represent the extra 1 hour period at the end of day light saving? In another, how can I use DateComponents to generate a Date which is capable to print the following? 2021 Sep 21 23:00:00 => 1632252600.0, Tuesday, September 21, 2021 at 11:00:00 PM Iran Standard Time Now, we understand that, in Tehran, during 2021 Sept 21, there are 2 type of 23:00:00 time 23:00:00 Iran Daylight time (Epoch is 1632249000) 23:00:00 Iran Standard time (Epoch is 1632252600) 23:00:00 Iran Daylight time (Epoch is 1632249000) I can represent the above using let date = date(year: 2021, month: 09, day: 21, hour: 23, minute: 00, second: 00) 23:00:00 Iran Standard time (Epoch is 1632252600) I have no idea how to represent the above. As, I do not find a way in DateComponents, to enable us to specific whether the local time is belong to standard time, or daylight time.
DateComponents do not have a time zone. The time zone comes into it when you convert DateComponents to a Date, using the call Calendar.date(from:). It's the calendar's time zone that determines how those DateComponents are converted to a Date. Instead of using Calendar.current, create a custom calendar and set it to the IRST time zone. (I couldn't figure out the time zone for Iran Daylight time. I would have expected it to have the abbreviation "IRDT", but that doesn't work.) Let's say we have a calendar irstCalendar that's set to Iran Standard Time ("IRST"). If you use irstCalendar.date(from: dateComponents) you'll always get the Date based on standard time. Consider this code: func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int, calendar: Calendar = Calendar.current) -> Date { var dateComponents = DateComponents() dateComponents.year = year dateComponents.month = month dateComponents.day = day dateComponents.hour = hour dateComponents.minute = minute dateComponents.second = second let date = calendar.date(from: dateComponents)! return date } guard let tehranStandardTimeZone = TimeZone(abbreviation: "IRST") else { fatalError("Can't create time zones") } var tehranSTCalendar = Calendar(identifier: .gregorian) tehranSTCalendar.timeZone = tehranStandardTimeZone let tehranDateFormatter = DateFormatter() tehranDateFormatter.dateStyle = .medium tehranDateFormatter.timeStyle = .medium tehranDateFormatter.timeZone = tehranStandardTimeZone let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59, calendar: tehranSTCalendar) let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00, calendar: tehranSTCalendar) let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01, calendar: tehranSTCalendar) print("STEP 1: 2021 Sep 21 23:59:59 => \(date1.timeIntervalSince1970), \(tehranDateFormatter.string(from:date1))") print("STEP 2: 2021 Sep 22 00:00:00 => \(date2.timeIntervalSince1970), \(tehranDateFormatter.string(from:date2))") print("STEP 3: 2021 Sep 22 00:00:01 => \(date3.timeIntervalSince1970), \(tehranDateFormatter.string(from:date3))") That outputs: STEP 1: 2021 Sep 21 23:59:59 => 1632252599.0, Sep 21, 2021 at 11:59:59 PM STEP 2: 2021 Sep 22 00:00:00 => 1632256200.0, Sep 22, 2021 at 12:00:00 AM STEP 3: 2021 Sep 22 00:00:01 => 1632256201.0, Sep 22, 2021 at 12:00:01 AM
Swift - Add N month to date
I have used the following code to generate dates between two dates. It works in all cases where the day of the month is less than 28. extension Date { public func addMonth(n: Int) -> Date { let calendar = Calendar.current return calendar.date(byAdding: .month, value: n, to: self)! } public func addYear(n: Int) -> Date { let calendar = Calendar.current return calendar.date(byAdding: .year, value: n, to: self)! } public var monthName: String { let calendar = Calendar.current let monthInt = calendar.component(.month, from: self) return calendar.monthSymbols[monthInt-1] } } var date = Date() repeat { date = date.addMonth(n: 1) print("\(date) \(date.monthName) ") } while date <= Date().addYear(n: 2) Result 2020-07-30 13:31:14 +0000 July 2020-08-30 13:31:14 +0000 August 2020-09-30 13:31:14 +0000 September 2020-10-30 14:31:14 +0000 October 2020-11-30 14:31:14 +0000 November 2020-12-30 14:31:14 +0000 December 2021-01-30 14:31:14 +0000 January 2021-02-28 14:31:14 +0000 February 2021-03-28 13:31:14 +0000 March 2021-04-28 13:31:14 +0000 April 2021-05-28 13:31:14 +0000 May 2021-06-28 13:31:14 +0000 June 2021-07-28 13:31:14 +0000 July 2021-08-28 13:31:14 +0000 August 2021-09-28 13:31:14 +0000 September 2021-10-28 13:31:14 +0000 October 2021-11-28 14:31:14 +0000 November 2021-12-28 14:31:14 +0000 December 2022-01-28 14:31:14 +0000 January 2022-02-28 14:31:14 +0000 February 2022-03-28 13:31:14 +0000 March 2022-04-28 13:31:14 +0000 April 2022-05-28 13:31:14 +0000 May 2022-06-28 13:31:14 +0000 June 2022-07-28 13:31:14 +0000 July Expected result I expect the result to be either 28 or 30. 2020-07-30 13:31:14 +0000 July 2020-08-30 13:31:14 +0000 August 2020-09-30 13:31:14 +0000 September 2020-10-30 14:31:14 +0000 October 2020-11-30 14:31:14 +0000 November 2020-12-30 14:31:14 +0000 December 2021-01-30 14:31:14 +0000 January 2021-02-28 14:31:14 +0000 February 2021-03-30 13:31:14 +0000 March 2021-04-30 13:31:14 +0000 April 2021-05-30 13:31:14 +0000 May 2021-06-30 13:31:14 +0000 June 2021-07-30 13:31:14 +0000 July 2021-08-30 13:31:14 +0000 August 2021-09-30 13:31:14 +0000 September 2021-10-30 13:31:14 +0000 October 2021-11-30 14:31:14 +0000 November 2021-12-30 14:31:14 +0000 December 2022-01-30 14:31:14 +0000 January 2022-02-28 14:31:14 +0000 February 2022-03-30 13:31:14 +0000 March 2022-04-30 13:31:14 +0000 April 2022-05-30 13:31:14 +0000 May 2022-06-30 13:31:14 +0000 June 2022-07-30 13:31:14 +0000 July Does Calendar has built-in functionality to achieve this?
As you observed, adding 1 month n times is not the same as adding n month. Apparently you want the latter, e.g. like this: let now = Date() let finalDate = now.addYear(n: 2) for n in 1... { let date = now.addMonth(n: n) print("\(date) \(date.monthName) ") if date > finalDate { break } } Or this: let now = Date() let finalDate = now.addYear(n: 2) let dates = (1...).lazy.map { now.addMonth(n: $0) } .prefix(while: { $0 <= finalDate } ) for date in dates { print("\(date) \(date.monthName)") }
You can use Calendar method nextDate(after:) passing previousTimePreservingSmallerComponents as the matchingPolicy: public extension Date { func noon(using calendar: Calendar = .current) -> Date { calendar.date(bySettingHour: 12, minute: 0, second: 0, of: self)! } func day(using calendar: Calendar = .current) -> Int { calendar.component(.day, from: self) } func adding(_ component: Calendar.Component, value: Int, using calendar: Calendar = .current) -> Date { calendar.date(byAdding: component, value: value, to: self)! } func monthSymbol(using calendar: Calendar = .current) -> String { calendar.monthSymbols[calendar.component(.month, from: self)-1] } } var date = Date().noon() // "Jun 30, 2020 at 12:00 PM" let day = date.day() let endDate = date.adding(.year, value: 2) repeat { date = Calendar.current.nextDate(after: date, matching: DateComponents(day: day, hour: 12), matchingPolicy: .previousTimePreservingSmallerComponents)! print(date.description(with: .current), date.monthSymbol()) } while date <= endDate this will print: Thursday, July 30, 2020 at 12:00:00 PM Brasilia Standard Time July Sunday, August 30, 2020 at 12:00:00 PM Brasilia Standard Time August Wednesday, September 30, 2020 at 12:00:00 PM Brasilia Standard Time September Friday, October 30, 2020 at 12:00:00 PM Brasilia Standard Time October Monday, November 30, 2020 at 12:00:00 PM Brasilia Standard Time November Wednesday, December 30, 2020 at 12:00:00 PM Brasilia Standard Time December Saturday, January 30, 2021 at 12:00:00 PM Brasilia Standard Time January Sunday, February 28, 2021 at 12:00:00 PM Brasilia Standard Time February Tuesday, March 30, 2021 at 12:00:00 PM Brasilia Standard Time March Friday, April 30, 2021 at 12:00:00 PM Brasilia Standard Time April Sunday, May 30, 2021 at 12:00:00 PM Brasilia Standard Time May Wednesday, June 30, 2021 at 12:00:00 PM Brasilia Standard Time June Friday, July 30, 2021 at 12:00:00 PM Brasilia Standard Time July Monday, August 30, 2021 at 12:00:00 PM Brasilia Standard Time August Thursday, September 30, 2021 at 12:00:00 PM Brasilia Standard Time September Saturday, October 30, 2021 at 12:00:00 PM Brasilia Standard Time October Tuesday, November 30, 2021 at 12:00:00 PM Brasilia Standard Time November Thursday, December 30, 2021 at 12:00:00 PM Brasilia Standard Time December Sunday, January 30, 2022 at 12:00:00 PM Brasilia Standard Time January Monday, February 28, 2022 at 12:00:00 PM Brasilia Standard Time February Wednesday, March 30, 2022 at 12:00:00 PM Brasilia Standard Time March Saturday, April 30, 2022 at 12:00:00 PM Brasilia Standard Time April Monday, May 30, 2022 at 12:00:00 PM Brasilia Standard Time May Thursday, June 30, 2022 at 12:00:00 PM Brasilia Standard Time June Saturday, July 30, 2022 at 12:00:00 PM Brasilia Standard Time July edit/update: If you need every nth month: var date = Date().noon() // "Jun 30, 2020 at 12:00 PM" let day = date.day() let endDate = date.adding(.year, value: 2) var dates: [Date] = [] let nthMonth = 3 var counter = 0 repeat { counter += 1 date = Calendar.current.nextDate(after: date, matching: DateComponents(day: day, hour: 12), matchingPolicy: .previousTimePreservingSmallerComponents)! if counter.isMultiple(of: nthMonth) { dates.append(date) print(date.description(with: .current), date.monthSymbol()) } } while date <= endDate This will print: Wednesday, September 30, 2020 at 12:00:00 PM Brasilia Standard Time September Wednesday, December 30, 2020 at 12:00:00 PM Brasilia Standard Time December Tuesday, March 30, 2021 at 12:00:00 PM Brasilia Standard Time March Wednesday, June 30, 2021 at 12:00:00 PM Brasilia Standard Time June Thursday, September 30, 2021 at 12:00:00 PM Brasilia Standard Time September Thursday, December 30, 2021 at 12:00:00 PM Brasilia Standard Time December Wednesday, March 30, 2022 at 12:00:00 PM Brasilia Standard Time March Thursday, June 30, 2022 at 12:00:00 PM Brasilia Standard Time June
where query in daterange in rails with postgresql
How to use where queries with daterange in postgresql with Rails 4.2: ConsultingLocation Load (0.6ms) SELECT "consulting_locations".* FROM "consulting_locations" WHERE "consulting_locations"."deleted_at" IS NULL AND "consulting_locations"."id" = $1 LIMIT 1 [["id", 495]] ConsultingLocationDoctorSchedule Load (1.7ms) SELECT "consulting_location_doctor_schedules".* FROM "consulting_location_doctor_schedules" INNER JOIN "consulting_location_doctors" ON "consulting_location_doctor_schedules"."consulting_location_doctor_id" = "consulting_location_doctors"."id" WHERE "consulting_location_doctors"."deleted_at" IS NULL AND "consulting_location_doctors"."consulting_location_id" = $1 [["consulting_location_id", 495]] => [#<ConsultingLocationDoctorSchedule:0x007fe7653f7538 id: 1, consulting_location_doctor_id: 495, schedule_date: Mon, 05 Jan 2015 00:00:00 IST +05:30, slot_details: [{"end"=>"2015-01-05T03:00:00.000+00:00", "start"=>"2015-01-05T02:30:00.000+00:00", "title"=>" 2:30 am to 3:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T03:30:00.000+00:00", "start"=>"2015-01-05T03:00:00.000+00:00", "title"=>" 3:00 am to 3:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T04:00:00.000+00:00", "start"=>"2015-01-05T03:30:00.000+00:00", "title"=>" 3:30 am to 4:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T04:30:00.000+00:00", "start"=>"2015-01-05T04:00:00.000+00:00", "title"=>" 4:00 am to 4:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T05:00:00.000+00:00", "start"=>"2015-01-05T04:30:00.000+00:00", "title"=>" 4:30 am to 5:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T05:30:00.000+00:00", "start"=>"2015-01-05T05:00:00.000+00:00", "title"=>" 5:00 am to 5:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T06:00:00.000+00:00", "start"=>"2015-01-05T05:30:00.000+00:00", "title"=>" 5:30 am to 6:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T06:30:00.000+00:00", "start"=>"2015-01-05T06:00:00.000+00:00", "title"=>" 6:00 am to 6:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T07:00:00.000+00:00", "start"=>"2015-01-05T06:30:00.000+00:00", "title"=>" 6:30 am to 7:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T07:30:00.000+00:00", "start"=>"2015-01-05T07:00:00.000+00:00", "title"=>" 7:00 am to 7:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T08:00:00.000+00:00", "start"=>"2015-01-05T07:30:00.000+00:00", "title"=>" 7:30 am to 8:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T08:30:00.000+00:00", "start"=>"2015-01-05T08:00:00.000+00:00", "title"=>" 8:00 am to 8:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T09:00:00.000+00:00", "start"=>"2015-01-05T08:30:00.000+00:00", "title"=>" 8:30 am to 9:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T09:30:00.000+00:00", "start"=>"2015-01-05T09:00:00.000+00:00", "title"=>" 9:00 am to 9:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T10:00:00.000+00:00", "start"=>"2015-01-05T09:30:00.000+00:00", "title"=>" 9:30 am to 10:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T10:30:00.000+00:00", "start"=>"2015-01-05T10:00:00.000+00:00", "title"=>"10:00 am to 10:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T11:00:00.000+00:00", "start"=>"2015-01-05T10:30:00.000+00:00", "title"=>"10:30 am to 11:00 am", "appointment_id"=>""}, {"end"=>"2015-01-05T11:30:00.000+00:00", "start"=>"2015-01-05T11:00:00.000+00:00", "title"=>"11:00 am to 11:30 am", "appointment_id"=>""}, {"end"=>"2015-01-05T12:00:00.000+00:00", "start"=>"2015-01-05T11:30:00.000+00:00", "title"=>"11:30 am to 12:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T12:30:00.000+00:00", "start"=>"2015-01-05T12:00:00.000+00:00", "title"=>"12:00 pm to 12:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T13:00:00.000+00:00", "start"=>"2015-01-05T12:30:00.000+00:00", "title"=>"12:30 pm to 1:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T13:30:00.000+00:00", "start"=>"2015-01-05T13:00:00.000+00:00", "title"=>" 1:00 pm to 1:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T14:00:00.000+00:00", "start"=>"2015-01-05T13:30:00.000+00:00", "title"=>" 1:30 pm to 2:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T14:30:00.000+00:00", "start"=>"2015-01-05T14:00:00.000+00:00", "title"=>" 2:00 pm to 2:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T15:00:00.000+00:00", "start"=>"2015-01-05T14:30:00.000+00:00", "title"=>" 2:30 pm to 3:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T15:30:00.000+00:00", "start"=>"2015-01-05T15:00:00.000+00:00", "title"=>" 3:00 pm to 3:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T16:00:00.000+00:00", "start"=>"2015-01-05T15:30:00.000+00:00", "title"=>" 3:30 pm to 4:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T16:30:00.000+00:00", "start"=>"2015-01-05T16:00:00.000+00:00", "title"=>" 4:00 pm to 4:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T17:00:00.000+00:00", "start"=>"2015-01-05T16:30:00.000+00:00", "title"=>" 4:30 pm to 5:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T17:30:00.000+00:00", "start"=>"2015-01-05T17:00:00.000+00:00", "title"=>" 5:00 pm to 5:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T18:00:00.000+00:00", "start"=>"2015-01-05T17:30:00.000+00:00", "title"=>" 5:30 pm to 6:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T18:30:00.000+00:00", "start"=>"2015-01-05T18:00:00.000+00:00", "title"=>" 6:00 pm to 6:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T19:00:00.000+00:00", "start"=>"2015-01-05T18:30:00.000+00:00", "title"=>" 6:30 pm to 7:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-05T19:30:00.000+00:00", "start"=>"2015-01-05T19:00:00.000+00:00", "title"=>" 7:00 pm to 7:30 pm", "appointment_id"=>""}], start_and_end_time: Mon, 05 Jan 2015...Tue, 06 Jan 2015, deleted_at: nil, deleted_by_id: nil, created_at: Wed, 31 Dec 2014 16:21:59 IST +05:30, updated_at: Wed, 31 Dec 2014 16:21:59 IST +05:30>, #<ConsultingLocationDoctorSchedule:0x007fe7653f7380 id: 2, consulting_location_doctor_id: 495, schedule_date: Tue, 06 Jan 2015 00:00:00 IST +05:30, slot_details: [{"end"=>"2015-01-06T09:30:00.000+00:00", "start"=>"2015-01-06T09:00:00.000+00:00", "title"=>" 9:00 am to 9:30 am", "appointment_id"=>""}, {"end"=>"2015-01-06T10:00:00.000+00:00", "start"=>"2015-01-06T09:30:00.000+00:00", "title"=>" 9:30 am to 10:00 am", "appointment_id"=>""}, {"end"=>"2015-01-06T10:30:00.000+00:00", "start"=>"2015-01-06T10:00:00.000+00:00", "title"=>"10:00 am to 10:30 am", "appointment_id"=>""}, {"end"=>"2015-01-06T11:00:00.000+00:00", "start"=>"2015-01-06T10:30:00.000+00:00", "title"=>"10:30 am to 11:00 am", "appointment_id"=>""}, {"end"=>"2015-01-06T11:30:00.000+00:00", "start"=>"2015-01-06T11:00:00.000+00:00", "title"=>"11:00 am to 11:30 am", "appointment_id"=>""}, {"end"=>"2015-01-06T12:00:00.000+00:00", "start"=>"2015-01-06T11:30:00.000+00:00", "title"=>"11:30 am to 12:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T12:30:00.000+00:00", "start"=>"2015-01-06T12:00:00.000+00:00", "title"=>"12:00 pm to 12:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T13:00:00.000+00:00", "start"=>"2015-01-06T12:30:00.000+00:00", "title"=>"12:30 pm to 1:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T13:30:00.000+00:00", "start"=>"2015-01-06T13:00:00.000+00:00", "title"=>" 1:00 pm to 1:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T14:00:00.000+00:00", "start"=>"2015-01-06T13:30:00.000+00:00", "title"=>" 1:30 pm to 2:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T14:30:00.000+00:00", "start"=>"2015-01-06T14:00:00.000+00:00", "title"=>" 2:00 pm to 2:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T15:00:00.000+00:00", "start"=>"2015-01-06T14:30:00.000+00:00", "title"=>" 2:30 pm to 3:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T15:30:00.000+00:00", "start"=>"2015-01-06T15:00:00.000+00:00", "title"=>" 3:00 pm to 3:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T16:00:00.000+00:00", "start"=>"2015-01-06T15:30:00.000+00:00", "title"=>" 3:30 pm to 4:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T16:30:00.000+00:00", "start"=>"2015-01-06T16:00:00.000+00:00", "title"=>" 4:00 pm to 4:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T17:00:00.000+00:00", "start"=>"2015-01-06T16:30:00.000+00:00", "title"=>" 4:30 pm to 5:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T17:30:00.000+00:00", "start"=>"2015-01-06T17:00:00.000+00:00", "title"=>" 5:00 pm to 5:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T18:00:00.000+00:00", "start"=>"2015-01-06T17:30:00.000+00:00", "title"=>" 5:30 pm to 6:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T18:30:00.000+00:00", "start"=>"2015-01-06T18:00:00.000+00:00", "title"=>" 6:00 pm to 6:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T19:00:00.000+00:00", "start"=>"2015-01-06T18:30:00.000+00:00", "title"=>" 6:30 pm to 7:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T19:30:00.000+00:00", "start"=>"2015-01-06T19:00:00.000+00:00", "title"=>" 7:00 pm to 7:30 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T20:00:00.000+00:00", "start"=>"2015-01-06T19:30:00.000+00:00", "title"=>" 7:30 pm to 8:00 pm", "appointment_id"=>""}, {"end"=>"2015-01-06T20:30:00.000+00:00", "start"=>"2015-01-06T20:00:00.000+00:00", "title"=>" 8:00 pm to 8:30 pm", "appointment_id"=>""}], start_and_end_time: Tue, 06 Jan 2015...Wed, 07 Jan 2015, deleted_at: nil, deleted_by_id: nil, created_at: Wed, 31 Dec 2014 16:21:59 IST +05:30, updated_at: Wed, 31 Dec 2014 16:21:59 IST +05:30>, Usually with simple date we would do Table.where(start_and_end_time: Date.yesterday..Date.today) I tried : where("start_and_end_time :#> ?",Date.yesterday..Date.today) threw this error: ConsultingLocation.find(495).schedules.where("start_and_end_time :#> ?",Date.yesterday..Date.today) ConsultingLocation Load (0.5ms) SELECT "consulting_locations".* FROM "consulting_locations" WHERE "consulting_locations"."deleted_at" IS NULL AND "consulting_locations"."id" = $1 LIMIT 1 [["id", 495]] PG::SyntaxError: ERROR: syntax error at or near ":" LINE 1: ...sulting_location_id" = $1 AND (start_and_end_time :#> '2014-... and it did not work. How to work with dateranges in general This also did not work: ConsultingLocation.find(495).schedules.where(start_and_end_time: Date.yesterday..Date.today) ConsultingLocation Load (103.0ms) SELECT "consulting_locations".* FROM "consulting_locations" WHERE "consulting_locations"."deleted_at" IS NULL AND "consulting_locations"."id" = $1 LIMIT 1 [["id", 495]] PG::InvalidTextRepresentation: ERROR: malformed range literal: "2015-01-01" LINE 1: ...on_doctor_schedules"."start_and_end_time" BETWEEN '2015-01-0... ^ DETAIL: Missing left parenthesis or bracket.
If you want to determine if a range contains another range: where("start_and_end_time && daterange(?, ?, '[]')", Date.yesterday, Date.today) If you want to know if a date falls within a range: where("start_and_end_time #> ?::date", Date.yesterday) I found these articles helpful: https://wiki.postgresql.org/images/7/73/Range-types-pgopen-2012.pdf https://wiki.postgresql.org/wiki/RangeTypes http://edgeguides.rubyonrails.org/active_record_postgresql.html#range-types https://www.postgresql.org/docs/9.3/static/rangetypes.html
Use where queries in JSONB datatype in Rails Postgres
How to query out schedules who has slot_details which have empty appointment_id. Here is an example data set: id: 98, consulting_location_doctor_id: 498, schedule_date: Thu, 15 Jan 2015 00:00:00 IST +05:30, slot_details: [{"end"=>"2015-01-15T15:00:00.000+00:00", "start"=>"2015-01-15T14:30:00.000+00:00", "title"=>" 2:30 pm to 3:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T15:30:00.000+00:00", "start"=>"2015-01-15T15:00:00.000+00:00", "title"=>" 3:00 pm to 3:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T16:00:00.000+00:00", "start"=>"2015-01-15T15:30:00.000+00:00", "title"=>" 3:30 pm to 4:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T16:30:00.000+00:00", "start"=>"2015-01-15T16:00:00.000+00:00", "title"=>" 4:00 pm to 4:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T17:00:00.000+00:00", "start"=>"2015-01-15T16:30:00.000+00:00", "title"=>" 4:30 pm to 5:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T17:30:00.000+00:00", "start"=>"2015-01-15T17:00:00.000+00:00", "title"=>" 5:00 pm to 5:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T18:00:00.000+00:00", "start"=>"2015-01-15T17:30:00.000+00:00", "title"=>" 5:30 pm to 6:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T18:30:00.000+00:00", "start"=>"2015-01-15T18:00:00.000+00:00", "title"=>" 6:00 pm to 6:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T19:00:00.000+00:00", "start"=>"2015-01-15T18:30:00.000+00:00", "title"=>" 6:30 pm to 7:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T19:30:00.000+00:00", "start"=>"2015-01-15T19:00:00.000+00:00", "title"=>" 7:00 pm to 7:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T20:00:00.000+00:00", "start"=>"2015-01-15T19:30:00.000+00:00", "title"=>" 7:30 pm to 8:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T20:30:00.000+00:00", "start"=>"2015-01-15T20:00:00.000+00:00", "title"=>" 8:00 pm to 8:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T21:00:00.000+00:00", "start"=>"2015-01-15T20:30:00.000+00:00", "title"=>" 8:30 pm to 9:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T21:30:00.000+00:00", "start"=>"2015-01-15T21:00:00.000+00:00", "title"=>" 9:00 pm to 9:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T22:00:00.000+00:00", "start"=>"2015-01-15T21:30:00.000+00:00", "title"=>" 9:30 pm to 10:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T22:30:00.000+00:00", "start"=>"2015-01-15T22:00:00.000+00:00", "title"=>"10:00 pm to 10:30 pm", appointment_id: ""}, {"end"=>"2015-01-15T23:00:00.000+00:00", "start"=>"2015-01-15T22:30:00.000+00:00", "title"=>"10:30 pm to 11:00 pm", appointment_id: ""}, {"end"=>"2015-01-15T23:30:00.000+00:00", "start"=>"2015-01-15T23:00:00.000+00:00", "title"=>"11:00 pm to 11:30 pm", appointment_id: ""}, {"end"=>"2015-01-16T00:00:00.000+00:00", "start"=>"2015-01-15T23:30:00.000+00:00", "title"=>"11:30 pm to 12:00 am", appointment_id: ""}], start_and_end_time: Thu, 15 Jan 2015...Fri, 16 Jan 2015, deleted_at: nil, deleted_by_id: nil, created_at: Tue, 30 Dec 2014 04:28:06 IST +05:30, updated_at: Tue, 30 Dec 2014 04:28:06 IST +05:30> I tried the example in guides as well. There is no example for where query on array of json. Please help.
Maybe this could help you: slot -> 'slot_details' #> '[{"end"=>"2015-01-15T20:00:00.000+00:00"}]' the idea is to ask if the partial subarray contained. If you were not in an array bun in an object it would instead be (let say we have a profile object): profile -> 'basics' #> '{"name":"john"}' don't be fooled trying to use ? here instead of #>
Rails Time Select with two range
I have to show a select box which have time from 9 Am to 11 Am Then 1Pm to 3pm with 15 minutes inteveral like the following: 9:00 AM 9:15 AM 9:30 AM . . . 10:45 AM 11:00 AM 01:00 PM 01:15 PM 01:30 PM . . . 2:45 PM 3:00 PM The above mentioned range will be dynamic but it has two intervals. Hows it is possible to achieve this?
First define the boundaries, start_time = DateTime.parse("9 AM").to_i start_interval = DateTime.parse("11 AM").to_i end_interval = DateTime.parse("1 PM").to_i end_time = DateTime.parse("3 PM").to_i Then use range and select to get the desired values, values = (start_time..end_time).step(15.minutes).select{|t| t <= start_interval || t >= end_interval } Then you can iterate over these values to generate select options, for example, select_tag :dt, options_for_select(values.map{ |t| [ Time.at(t).utc.to_datetime.strftime("%H:%M %p"), Time.at(t).utc.to_datetime ] } ) You can try this in console, > (start_time..end_time).step(15.minutes).select{|t| t <= start_interval || t >= end_interval }.map{ |t| Time.at(t).utc.to_datetime.strftime("%H:%M %p") } => ["09:00 AM", "09:15 AM", "09:30 AM", "09:45 AM", "10:00 AM", "10:15 AM", "10:30 AM", "10:45 AM", "11:00 AM", "13:00 PM", "13:15 PM", "13:30 PM", "13:45 PM", "14:00 PM", "14:15 PM", "14:30 PM", "14:45 PM", "15:00 PM"]