ISODateTime
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © thomastthai
// @version=5

// @description Library functions to work with ISO 8601 date and time string. It's especially helpful on a daily timeframe when working with timestamp() for a time that occurs after the bar's open time (but same day), and the label or drawing is printed on the next day instead being drawn on the day in the date string.

library(title='ISODateTime')

// @function Get year, month, day from date string.
// @param dateStr <string> : ISO 8601 format, i.e. "2022-05-04T14:00:00.001000-04:00" or "2022-05-04T14:00:00Z"
// @returns int [YYYY, MM, DD]
export getDateParts(string dateStr) =>
    var _year = int(na)
    var _month = int(na)
    var _day = int(na)
    var dateStrUpper = str.upper(dateStr)

    datePart = str.match(dateStrUpper, "[\\d]{4}-[\\d]{2}-[\\d]{2}")

    // get date parts
    if str.length(datePart) > 0
        _year := math.round(str.tonumber(array.get(str.split(datePart, "-"), 0)))
        _month := math.round(str.tonumber(array.get(str.split(datePart, "-"), 1)))
        _day := math.round(str.tonumber(array.get(str.split(datePart, "-"), 2)))

    [_year, _month, _day]

// @function Get hour, minute, seconds from date string.
// @param dateStr <string> : ISO 8601 format, i.e. "2022-05-04T14:00:00.001000-04:00" or "2022-05-04T14:00:00Z"
// @returns int [HH, MM, SS, MS]
export getTimeParts(string dateStr) =>
    var _hour = int(na)
    var _minute = int(na)
    var _second = int(na)
    var _millisecond = 0
    var dateStrUpper = str.upper(dateStr)

    timePart = str.match(dateStrUpper, "[\\d]+:[\\d]+:[\\d]+")

    // get military time
    if str.length(timePart) > 0
        _hour := math.round(str.tonumber(array.get(str.split(timePart, ":"), 0)))
        _minute := math.round(str.tonumber(array.get(str.split(timePart, ":"), 1)))
        _second := math.round(str.tonumber(array.get(str.split(timePart, ":"), 2)))
   
    // get milliseconds
    if str.length(str.match(dateStrUpper, "\.[\\d]+")) > 0
        _millisecond := math.round(str.tonumber(str.match(dateStrUpper, "\.[\\d]+")) * 1000)
    
    [_hour, _minute, _second, _millisecond]

// @function Get UTC timezone.
// @param dateStr <string> : ISO 8601 format, i.e. "2022-05-04T14:00:00.001000-04:00" or "2022-05-04T14:00:00Z"
// @returns string UTC timezone
export getUTCTimezone(string dateStr) =>
    var dateStrUpper = str.upper(dateStr)
    var _timezone = string(na)
 
    // get timezone
    if str.endswith(dateStrUpper, "Z")
        _timezone := "UTC" + "+00::00"
    else
        _timezone := "UTC" + str.match(dateStrUpper, "[+-][\\d]+:[\\d]+$")