Pine-Script - Input actual time as Default - time

i´m trying to fill a Date input with a default value, the default value should be the actual date.
The original code:
end_time = input.time(defval=timestamp('01 Aug 2021 00:00 +0000'), title='End Time')
I would like to have the actual date as defval.
i tried several things, like timestamp(timenow) but i get always the same error-message:
An argument of 'series int' type was used but a 'const string' is expected
I understand that i bring a int to a string, but how can i convert the actual date/time to fit in the code above?
Thanx for your brains,

The input.*() function defval= argument requires a value known at the compilation time and could not be dynamic.
As a workaround, you can use the interactive feature (confirm= argument) to select the last bar on the chart with a mouse-click:
//#version=5
indicator("My script")
end_time = input.time(defval=timestamp('01 Aug 2021 00:00 +0000'), title='End Time', confirm = true)
bgcolor(time == end_time ? color.red : na)

Related

How to get the same output of departed Date.parse() in groovy?

I have an application that runs the old version of the spring application. The application has the function to create date objects using Date.parse as follows
Date getCstTimeZoneDateNow() {
String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def zonedDateString = new Date().format(dateFormat, TimeZone.getTimeZone('CST'))
Date date = Date.parse(dateFormat, zonedDateString)
return date // Tue Oct 18 20:36:12 EDT 2022 (in Date)
}
However, the code above is deprecated. I need to produce the same result.
I read other posts and it seems like Calender or SimpleDateFormatter is preferred.
And I thought SimpleDateFormatter has more capabilities.
This post helped me understand more about what is going on in the following code
SimpleDateFormat parse loses timezone
Date getCstTimeZoneDateNow() {
Date now = new Date()
String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
SimpleDateFormat sdf = new SimpleDateFormat()
sdf.setTimeZone(TimeZone.getTimeZone('CST'))
// cstDateTime prints times in cst
String cstDateTime = sdf.format(now) // 2022-10-18T20:36:12.088Z (in String)
// JVM current time
Date date = sdf.parse(cstDateTime) // Tue Oct 18 21:36:12 EDT 2022 (in Date)
return date
}
Here my goal is to return the date object that is in the format of Tue Oct 18 20:36:12 EDT 2022
The format is good. However, like the post says, when I do sdf.parse(), it prints in JVM time.
This means, the format is good but the time zone is off.
How can I get the exact same result as before?
It does not have to use SimpleDateFormatter. Could be anything.
Thank you so much for reading and for your time.
Perhaps the important thing is, that the Date is always neutral to the timezone. Given example shows what is to be expected to work from the Java specs:
def format = new SimpleDateFormat()
format.setTimeZone(TimeZone.getTimeZone("CST"))
println new Date()
def date = format.parse(format.format(new Date()))
printf "parsed to %s%n", date
printf "formatted to %s (%s)%n", format.format(date), format.getTimeZone().getDisplayName()
In the output, notice when using the Format and when the toString(), a different time is shown accordingly, which is perfectly fine, since first we format and then parse again in the same format, thus the same time-zone. Later, we use the Date.toString() to output the date, this time using the system default time-zone which is always used when Date.toString() is called. In the output, the time-zone shift is reflected:
Thu Oct 20 09:22:58 EDT 2022
parsed to Thu Oct 20 09:22:00 EDT 2022
formatted to 10/20/22 8:22 AM (Central Standard Time)

Error parsing time string with timezone as "GMT+0000"

I am trying to parse "Tue Jun 11 2019 13:26:45 GMT+0000" with "Mon Jan 02 2006 15:04:05 MST-0700" as a layout string using time.Parse but I get this error parsing time "Tue Jun 11 2019 13:26:45 GMT+0000" as "Mon Jan 02 2006 15:04:05 MST-0700": cannot parse "" as "-0700".
I've been using above layout string for other offsets and it works fine. But, I think "+0000" is not being considered a valid offset or something? Any suggestions would be helpful.
EDIT: Using "Mon Jan 02 2006 15:04:05 GMT-0700" as the layout works and I get the output as 2019-06-11 13:26:45 +0000 +0000.
EDIT 2: According to reply in github issues, it turns out that in layout string "MST-0700" is actually two time zone value "MST" and numeric time zone value "-0700" which takes precedence over the former. And "GMT+08" or "GMT+00" is considered as a time zone value as a whole and matches against "MST". So it would be "GMT+08+0800" for "MST-0700".
I rarely touches time zone related problems, but I personally think this behaviour is confusing.
Original answer:
This is a bug confusing behaviour of Go's time library. While I am not certain of the desired behaviour of GMT time format (since I rarely see something like GMT+0800 or so in a time format string), the code logic that make GMT+0800 valid but GMT+0000 does not makes sense.
I have submitted an issue on the github: https://github.com/golang/go/issues/40472
In short, Go's time library parses format by consuming the layout string and the value string together. And currently when parsing a "GMT" time zone, it consumes more of the value string, if the following value string (say, "+0800" or "+0000") is signed and in range from -23 to +23. So not only does "GMT+0000" fails, but "GMT+0030" and "GMT+08" (when matching to `"MST-07") fails too.
Here is the detail: When parsing time zone, it checks the layout string and found "MST", so it tries to parse the time zone value in the value string, which at that time only has "GMT+0X00" (where X is '0' or '8') - others have been consumed (correctly). Source
case stdTZ:
// Does it look like a time zone?
if len(value) >= 3 && value[0:3] == "UTC" {
z = UTC
value = value[3:]
break
}
n, ok := parseTimeZone(value)
if !ok {
err = errBad
break
}
zoneName, value = value[:n], value[n:]
It's all good here. The parseTimeZone function makes a special case for GMT format for reason that is not obvious to me, but here is the code:
// Special case 2: GMT may have an hour offset; treat it specially.
if value[:3] == "GMT" {
length = parseGMT(value)
return length, true
}
And then parseGMT code is like this:
// parseGMT parses a GMT time zone. The input string is known to start "GMT".
// The function checks whether that is followed by a sign and a number in the
// range -23 through +23 excluding zero.
func parseGMT(value string) int {
value = value[3:]
if len(value) == 0 {
return 3
}
return 3 + parseSignedOffset(value)
}
From the comment, we can already sense problem: "+0800" is not a number in range from -23 to +23 excluding leading zero (while "+0000") is. And obviously, this function is trying to indicate (from the return value) to consume more than 3 bytes, that is more than the "GMT". We can confirm it in code of parseSignedOffset.
// parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
// The function checks for a signed number in the range -23 through +23 excluding zero.
// Returns length of the found offset string or 0 otherwise
func parseSignedOffset(value string) int {
sign := value[0]
if sign != '-' && sign != '+' {
return 0
}
x, rem, err := leadingInt(value[1:])
// fail if nothing consumed by leadingInt
if err != nil || value[1:] == rem {
return 0
}
if sign == '-' {
x = -x
}
if x < -23 || 23 < x {
return 0
}
return len(value) - len(rem)
}
Here, leadingInt is an uninteresting function that converts the prefix of a string to an int64, and the remaining part of the string.
So parseSignedOffset did what the documentation advertises: it parse the value string and see if it is in the range form -23 to +23, but at face value:
It considers +0800 as 800, larger than +23, so it returns 0. As a result, the parseGMT (and parseTimeZone) returns 3, so the Parse function only consumes 3 bytes this time, and leave "+0800" to match with "-0700", so it is parsed correctly.
It considers +0000 as 0, a valid value in the range, so it returns 5, meaning "+0000" is part of the time zone, and thus parseGMT (and parseTimeZone) returns 8, making the Parse function consumes the whole string, leaving "" to match with "-0700", and hence the error.
EDIT:
Using GMT in format string and get the "right" value is because that the "GMT" in format string is not considered as time zone, but a part of the format (just like spaces in the string), and "GMT" time zone is the same as the default time zone ("UTC").
You can time.Parse("Mon Jan 02 2006 15:04:05 XYZ-0700", "Tue Jun 11 2019 13:26:45 XYZ+0800") without getting an error.

How can I return LocalDate.now() in milliseconds?

I create date now:
ZoneId gmt = ZoneId.of("GMT");
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDateNow = localDateTime.toLocalDate();
Then I want return this date in milliseconds:
localDateNow.atStartOfDay(gmt) - 22.08.2017
localDateNow.atStartOfDay(gmt).toEpochSecond(); - 1503360000 (18.01.70)
How can I return LocalDate.now() in milliseconds?
Calling toInstant().toEpochMilli(), as suggested by #JB Nizet's comment, is the right answer, but there's a little and tricky detail about using local dates that you must be aware of.
But before that, some other minor details:
Instead of ZoneId.of("GMT") you can use the built-in constant ZoneOffset.UTC. They're equivalent, but there's no need to create extra redundant objects if the API already provides one that does exactly the same thing.
Instead of calling LocalDateTime.now() and then .toLocalDate(), you can call LocalDate.now() directly - they're equivalent.
Now the tricky details: when you call the now() method (for either LocalDateTime or LocalDate), it uses the JVM's default timezone to get the values for the current date, and this value might be different depending on the timezone configured in the JVM.
In the JVM I'm using, the default timezone is America/Sao_Paulo, and the local time here is 09:37 AM. So LocalDate.now() returns 2017-08-22 (August 22th 2017).
But if I change the default timezone to Pacific/Kiritimati, it returns 2017-08-23. That's because in Kiritimati, right now is already August 23th 2017 (and the local time there, at the moment I write this, is 02:37 AM).
So, if I run this code when the default timezone is Pacific/Kiritimati:
LocalDate dtNow = LocalDate.now(); // 2017-08-23
System.out.println(dtNow.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
The output is:
1503446400000
Which is the equivalent of August 23th 2017 at midnight in UTC.
If I run the same code when the default timezone is America/Sao_Paulo, the result will be:
1503360000000
Which is the equivalent of August 22th 2017 at midnight in UTC.
Using now() makes your code depends on the JVM's default timezone. And this configuration can be changed without notice, even at runtime, making your code return different results when such change occurs.
And you don't need such an extreme case (like someone misconfiguring the JVM to a "very-far" timezone). In my case, for example, in America/Sao_Paulo timezone, if I run the code at 11 PM, LocalDate will return August 22th, but the current date in UTC will already be August 23th. That's because 11 PM in São Paulo is the same as 2 AM of the next day in UTC:
// August 22th 2017, at 11 PM in Sao Paulo
ZonedDateTime z = ZonedDateTime.of(2017, 8, 22, 23, 0, 0, 0, ZoneId.of("America/Sao_Paulo"));
System.out.println(z); // 2017-08-22T23:00-03:00[America/Sao_Paulo]
System.out.println(z.toInstant()); // 2017-08-23T02:00:00Z (in UTC is already August 23th)
So using a LocalDate.now() is not a guarantee that I'll always have the current date in UTC.
If you want the current date in UTC (regardless of the JVM default timezone) and set the time to midnight, it's better to use a ZonedDateTime:
// current date in UTC, no matter what the JVM default timezone is
ZonedDateTime zdtNow = ZonedDateTime.now(ZoneOffset.UTC);
// set time to midnight and get the epochMilli
System.out.println(zdtNow.with(LocalTime.MIDNIGHT).toInstant().toEpochMilli());
The output is:
1503360000000
Which is the equivalent of August 22th 2017 at midnight in UTC.
Another alternative is to pass the timezone to LocalDate.now, so it can get the correct values for the current date on the specified zone:
// current date in UTC, no matter what the JVM default timezone is
LocalDate dtNowUtc = LocalDate.now(ZoneOffset.UTC);
// set time to midnight and get the epochMilli
System.out.println(dtNow.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());

Formatting date without lading zero to the day [duplicate]

This question already has answers here:
date format function to display date as "Jan 13 2014"
(3 answers)
Closed 7 years ago.
I writing a code in VBScript, but I cannot get the datetime part right.
I'm using FormatDateTime(now), but the gives not the best result like
FormatDateTime(now)
8-01-2016 9:05:12 becomes 01-08-2016 9:05:12.
28-01-2016 19:01:18 stays 28-01-2016 19:01:18.
Has to be:
8-01-2016 9:05:12
28-01-2016 19:01:18
Is there a way to get both the same?
Try using the format argument of FormatDateTime.
FormatDateTime(now, 2) 'This should return in mm/dd/yy format
More info here.
http://www.w3schools.com/asp/func_formatdatetime.asp
format (Optional) A value that specifies the date/time format to use
Can take the following values:
0 = vbGeneralDate - Default. Returns date: mm/dd/yy and time if
specified: hh:mm:ss PM/AM.
1 = vbLongDate - Returns date: weekday,
monthname, year
2 = vbShortDate - Returns date: mm/dd/yy
3 =
vbLongTime - Returns time: hh:mm:ss PM/AM
4 = vbShortTime - Return
time: hh:mm
This should do what you want.
od = "28-01-2016 19:01:18"
nd = FormatDateTime(od,0)
MsgBox(nd)
Output: 1/28/2016 7:01:18 PM

Rails DateTime gives invalid date sometimes and not others

I've got a bunch of user-inputted dates and times like so:
date = "01:00pm 06/03/2015"
I'm trying to submit them to a datetime column in a database, and I'm trying to systemize them like this:
DateTime.strptime(date, '%m/%d/%Y %H:%M')
But I consistently get an invalid date error. What am I doing wrong? If I submit the string without strptime the record will save but it sometimes gets the date wrong.
Also, how can I append a timezone to a DateTime object?
Edit:
So .to_datetime and DateTime.parse(date) work for the date string and fail for date2. What's going on?
date2 = "03:30pm 05/28/2015"
Try using to_datetime:
date.to_datetime
# => Fri, 06 Mar 2015 13:00:00 +0000
Also if you read the documentation for DateTime#strptime, here. It states:
Parses the given representation of date and time with the given
template, and creates a date object.
Its important to note that the template sequence must match to that of input string sequence, which don't in your case - leading to error.
Update
Using to_datetime over second example will generate
ArgumentError: invalid date
This is because it expects the date to be in dd-mm-yy format. Same error will be raised for DateTime.parse as to_datetime is nothing but an api for the later. You should use strptime in-case of non-standard custom date formats. Here:
date2 = "03:30pm 05/28/2015"
DateTime.strptime(date2, "%I:%M%p %m/%d/%Y")
# => Thu, 28 May 2015 15:30:00 +0000
date = "01:00pm 06/03/2015"
DateTime.parse(date)
=> Fri, 06 Mar 2015 13:00:00 +0000
You haven't got your parameters in the correct order.
DateTime.strptime(date, '%H:%M%p %m/%d/%Y')
You'll also need to add %p for the am/pm suffix

Resources