QTimeZone::QTimeZone(int offsetSeconds) - qt

I am using Qt 5.4.1 and getting issue during calling QTimeZone::QTimeZone(int offsetSeconds) method. My code is :
QTimeZone zone = QTimeZone(+19800); // +19800 is offsetFromUtc in seconds for India country
qDebug()<<QLocale::countryToString(zone.country());
The above qDebug prints "Default" each time but when I am using QTimeZone(const QByteArray & ianaId) method for example :
QTimeZone zone = QTimeZone("Asia/Calcutta");
qDebug()<<QLocale::countryToString(zone.country());
The above qDebug prints "India" which is correct. But at the same time QTimeZone(int offsetSeconds) method is not working properly.....could anybody help me what I am doing wrong ?

There is no way to convert a timezone offset into a country. The relationship is 1:n from locality to offset: if you know the region/country, and current UTC, you can know the timezone offset. But there is a lot of different locales that have the same offset. And the offset it not necessarily constant over time for any given location.

Related

Pine Script: How to display current time in chart's timezone on label, at every price update?

I am attempting to do something seemingly trivial, but running into all sorts of problems.
I would like to plot certain basic information on a label every time there is an update to the current price--regardless of the timeframe of my chart.
I am able to accurately display volume and price information, however displaying the time has been a challenge.
My first attempt was to use the following code:
if (barstate.islast)
label.set_text(
id=myLabel,
text="\nTime: " + tostring(hour) + ":" + tostring(minute) + ":" + tostring(minute)
)
I quickly learned that, even though my chart is set to the timezone for New York (i.e., UTC-4), calling tostring(hour) displays the hour of UTC.
Figuring out how to specify that I want it displayed time to correspond to my chart's timezone has been the first major hurdle, and I have tangled endlessly with timestamp() and syminfo.timezone to no avail.
My second major problem is that tostring(second) does not properly display the seconds, even for UTC time.
While working on a 1m chart, I thought I managed to solve this by implementing
tostring((timenow-time)/1000)
However, the seconds do not display properly on different time frames.
This is all in addition to the fact that charts from different exchanges in different time zones will all display time "incorrectly" with respect to UTC time.
It must to be the case that I am missing something fairly basic, since time is such crucial data, but I just can't determine the proper syntax.
Thanks in advance for any assistance.
A few different issues are at play here:
Pine scripts have no visibility on the chart's timezone you may have selected manually. That only affects the display of the chart.
The minute variable returns the minute at the beginning of the bar, so will not change on script iterations in the realtime bar, until a new bar begins. To get the current minute you will need to use an overloaded version of minute where you can specify a timestamp in ms. The timenow built-in variable returns the timestamp for the time of a particular script iteration (that is true in the realtime bar; when the script is running on historical bars, timenow is only updated every second during the script's execution). So you need to use minute(timenow).
If you want minute() to return a time in another timezone than the exchange's, you can use a second parameter to specify a timezone, which is what we do in the second example here. In our example you can change the timezone through the script's "Settings/Inputs". Used with the timezone, minute() will look something like:
minute(timenow, "GMT-4").
//#version=4
study("", "Time", true)
i_timeZone = input("GMT-4")
f_print(_txt) => var _lbl = label.new(bar_index, highest(10)[1], _txt, xloc.bar_index, yloc.price, #00000000, label.style_none, color.gray, size.large, text.align_left), label.set_xy(_lbl, bar_index, highest(10)[1]), label.set_text(_lbl, _txt)
f_print(tostring(hour(timenow), "00:") + tostring(minute(timenow), "00:") + tostring(second(timenow), "00") + " (Exchange)\n")
f_print(tostring(hour(timenow, i_timeZone), "00:") + tostring(minute(timenow, i_timeZone), "00:") + tostring(second(timenow, i_timeZone), "00") + " (Input: " + i_timeZone + ")")

What does moment(testDate, "x") do?

I have the following piece of code before me:
var testDate = 1481103000000;
var enterTime = moment(testDate, "x");
console.log(enterTime);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.js"></script>
The variable enterTime results in a momentjs object with an additional _f property set to "x" and a _pf property of type object (see the console log) compared to a normal moment(testDate) object.
I couldn't find information on the _f or _pf properties anywhere.
Can anyone tell me what the "x" stands for and for what reason it is being used?
Thanks in advance.
With moment(testDate, "x"); you are creating a moment object using moment(String, String); function specifying x as format (Unix ms timestamp).
When you do moment(testDate), you are creating a moment object using moment(Number);.
All moment properties starting with _ are for internal use, _f stands for format, while _pf stand for Parsing Flags.
You can have a look to moment code to get more details about _f and _pf.
x denotes Unix ms timestamp
Please note that this parameter is case-sensitive:
X Output: 1410715640.579 Unix timestamp
x Output: 1410715640579 Unix ms timestamp
Refer here for all the options.

Get local time in seconds using Qt

I am stuck with this problem.
I already got the currentUTCtime in seconds from the QDateTime.
Problem is, I can't find a possible way to convert this into the local time in seconds. There are some QDate functions like toLocalTime() which just don't seem to work. I hope somebody here can help me.
QDateTime::currentMSecsSinceEpoch();
QDateTime currentateTime = QDateTime::currentDateTime();
QDateTime UTC(QDateTime::currentDateTimeUtc());
currentDateTime.toString().toStdString();
TimeNow = currentDateTime.toMSecsSinceEpoch()/1000;
Above is my code for the currentUTC Time in seconds.
If you just need the time in seconds since the epoch you can use QDateTime::toTime_t(); this method exists in Qt 4.7 and seems to be a part of Qt 5 from the start, too.
QDateTime::currentDateTime().toTime_t()
for local time, or for UTC
QDateTime::currentDateTimeUtc().toTime_t()
Use QDateTime::fromTime_t, to which the documentation states:
Returns a datetime whose date and time are the number of seconds that have passed since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC) and converted to the given spec.
qint64 utcTime = QDateTime::currentMSecsSinceEpoch();
QDateTime localTime = QDateTime::fromTime_t(utcTime, Qt::LocalTime);

GAS function returns incorrect date - is it me or is it a defect?

Unless I use the .toLocaleDateString() method, the function below returns a date that is one day less than it should be. Am I doing something wrong or is this a defect?
function myDate() {
var sDate = '05/10/2012';
var parts = sDate.split('/');
var d = new Date( parts[2], parts[1]-1, parts[0]);
Logger.log(d);
Logger.log(d.toLocaleDateString());
};
The Logger returns:
Thu Oct 04 16:00:00 PDT 2012
05 October 2012 00:00:00 BST
I'm in the UK, hence the UK date format. I've checked that my project properties have the time zone set to "(GMT+00:00) London" so why does the Logger show the first date in PDT? Is that the reason for the wrong date? I've reproduced the problem in a stand-alone project. Here's a link to it.
I wanted to convert the string variable into a date object in order to do some date math so having to convert back to a string with .toLocaleDateString() method isn't helpful.
I've checked for consistence, thinking perhaps I could work around it, by testing with other dates. Bizarrely, if I change the value of sDate to anything between 01/01/2012 & 04/03/2012 it returns accurately. From 05/03/2012 onwards it drops a day. With 2013 dates, it returns correctly until 29/04/2013 when it starts dropping a day again. So it's not consistent. It seems similar to the problem reported here.
I found that dates read by the getValues() function on a range that were between the old DST rules and the new DST rules were decremented by 1 hour. So, the implicit time for the date "10/30/2012" is 00:00:00. But, when read in, it was decrementing by an hour, landing it in the previous day, i.e. 10/29/2012 23:00:00.
Any date between these two timeframes, not inclusive of the start day but inclusive of the end day, will exhibit this behavior currently, at least as read by the getValues() function:
Between the last Sunday in October and the first Sunday in November
Between the second Sunday in March and first Sunday in April.
I ended up writing code that would dynamically calculate these dates for the current year and if the date landed in the target range, I would simply increment it by an hour. This may be the the long way to fix it, but it works.
Here is my code:
/*
The old rules for DST stated that the time change occurred on the last Sunday in October,
which would be 10/28/2012. So, when you type in 10/29/2012, the timestamp associated with the date (00:00:00) is being decremented by an hour (23:00:00),
which drops it into the previous day. The new rules for DST states that DST ends on the 1st Sunday in November, which is 11/04/2012. Also, the DST rules
for springtime are also an impacted range of dates that exhibit this behavior, between the second sunday in March and the first sunday in April.
Note: Running this function from the script editor does not produce the strange DST behavior. It seems to be an issue with the getValues() function on a Range object.
*/
function fixDateDSTProblem(lstrDate){
var d = new Date(lstrDate);
//Example ranges affected
//10/29/2012 - 11/04/2012
//03/11/2013 - 04/07/2013
if(isNaN(d.getMonth())){
//return what was passed in if it's not a date or null.
return lstrDate;
}
else if(isAffectedDate(d)){
//increment by one hour
return new Date(d.getTime() + (60 * 60 * 1000));
}
else{
//date is not affected, simply return it as it was passed.
return lstrDate;
}
}
//Check to see if a date is within a beginning and end date
function dateWithin(beginDate,endDate,checkDate) {
var b,e,c;
b = Date.parse(beginDate);
e = Date.parse(endDate);
c = Date.parse(checkDate);
//slightly modified this for the date checking since beginning date is not inclusive, so needs to be > instead of >=
if((c <= e && c > b)) {
return true;
}
return false;
}
function isAffectedDate(targetDate){
var yearNum = targetDate.getFullYear();
//Get the last Sunday in October
var lastSunOctDateStr = getLastOccurrenceDate(0, 10, yearNum);
//Get the first Sunday in November
var firstSunNovDateStr = getOccurrenceDate(1, 0, 11, yearNum);
//Get the second Sunday in March
var secondSunMarDateStr = getOccurrenceDate(2, 0, 3, yearNum);
//Get the first Sunday in April
var firstSunAprDateStr = getOccurrenceDate(1, 0, 4, yearNum);
//if the date is between the last sunday in october and the first sunday in november
// or if the date is between the second sunday in march and the first sunday and april, fix it up!
if(dateWithin(lastSunOctDateStr, firstSunNovDateStr, targetDate) ||
dateWithin(secondSunMarDateStr, firstSunAprDateStr, targetDate)){
return true;
}
return false;
}
function getOccurrenceDate(numOccurrence, dayIndex, monthCalendar, yearNum){
//"Get date of first occurrence of Monday in June 2013"
//"Get date of the second occurrence of Sunday in April 2013"
//dayIndex: Sunday = 0, Saturday = 6
var monthIndex = monthCalendar - 1;
var numFirstXDay = null;
var firstDay = new Date(monthCalendar+"/01/"+yearNum);
var numDayOfWeek = firstDay.getDay();
if(numDayOfWeek == dayIndex){
numFirstXDay = 1;
}
else if(numDayOfWeek > dayIndex){
numFirstXDay = 1+(6-numDayOfWeek)+1+dayIndex+(7*(numOccurrence-1));
}
else if(numDayOfWeek < dayIndex){
numFirstXDay = 1+(dayIndex - numDayOfWeek)+(7*(numOccurrence-1));
}
return monthCalendar+"/"+numFirstXDay+"/"+yearNum;
}
function getLastOccurrenceDate(dayIndex, monthCalendar, yearNum){
//Example: "Get date of last occurrence of Monday in June 2013"
var monthIndex = monthCalendar - 1;
var numLastXDay = null;
//TODO: Handle Leap Year!
var monthMaxDaysArray = {
'1':'31',
'2':'28',
'3':'31',
'4':'30',
'5':'31',
'6':'30',
'7':'31',
'8':'31',
'9':'30',
'10':'31',
'11':'30',
'12':'31'}
var lastDay = new Date(monthCalendar + "/"+monthMaxDaysArray[monthCalendar]+"/" + yearNum);
var numDayOfWeek = lastDay.getDay();
if(numDayOfWeek == dayIndex){
numLastXDay = 31;
}
else if(numDayOfWeek > dayIndex){
numLastXDay = monthMaxDaysArray[monthCalendar] - (numDayOfWeek - dayIndex);
}
else if(numDayOfWeek < dayIndex){
numLastXDay = (monthMaxDaysArray[monthCalendar] - numDayOfWeek) - (6 - (dayIndex-1));
}
return monthCalendar + "/" + numLastXDay + "/" + yearNum;
}
The logger always logs dates in PDT. It's the same instance of time, just represented a different way. You are seeing that + differences in daylight savings time.
Even if Corey's answer doesn't need any confirmation (he knows what he is talking about ;) let me add some practical details ...
every javascript manipulation you do on date object (getDay, getTime, getFulYear...) will return correct values even if the logger value you see seems wrong so you don't need to convert to string and back to numbers if you need to manipulate dates
If these dates are shown in a spreadsheet then the spreadsheet locale settings will be used to show the desired values.
Sometimes you will see the values in other format in the logger... don't ask when or why but it happens to me sometimes (I'm in GMT+1 Belgium)
The date shift you notice in october and april are indeed happening when daylight savings starts and stops and this can become tricky when you need to define a date in a calendar event in one period from another (for example today I create an event in december there will be 1 hour difference) so you need to use the right GMT+0X00 value when you read a date object in a user interface using utilities.formatDate
If for some reason you show a list of dates starting before daylight savings switch day and ending after, and you use utilities.formatDate, it is better to user a variable to play with 'GMT+0X00' dynamically : I get it simply using something like this :
* EDIT* since a few weeks the syntax has changed and this string has to be formated differently, so I updated this code accordingly. (see issue 2204)
`var FUS1=new Date().toString().substr(25,6)+":00";// FUS1 gets the GMT+02:00 or GMT+01:00 string`
Hoping it's getting clear enough
Sorry to join the party a few months late...
The problem with these answers is that none of them actually make it clear that this is a BUG. Or, to be more precise, this is something that Google have decided is "correct" behaviour (see Issue 1271, for example, closed with no action), when it quite clearly is completely the wrong thing to do.
Consider this. I want to put someone's birthdate in a spreadsheet, and I have a large list of them. I then want to read out the value and put it in a form:
function getAge(ss, index) {
var ages = ss.getRangeByName("birthDates").getValues();
return ages[index];
}
...
app.createLabel(getAge(ss, index));
The form now contains the wrong birthdate for everyone born between April and October. Google has decided that they were actually born one day earlier. Or try to read out the ages, and put them in another spreadsheet, with no processing, where both spreadsheets have the same time zone setting. Same story, and it leaves me looking really stupid when people mail to tell me that I've got their birthdates wrong.
This is how it should be done: if someone manually specifies a date, for example "06/06/1997", then reads that date with getValue, they expect to get "06/06/1997" back, not the day before. They really don't expect you to try to second guess them: "Ok, this date happens to be during DST, so what they really expect to read back from getValue is something corrected to non-DST, so why don't we subtract an hour and give them the day before?"
It's crazy. If Excel did that, it would be a laughing stock. Fix it, please.
EDIT
Serge, that's very interesting, but your spreadsheet shows a work-around which extracts a TZ, and then displays according to that TZ. But that just avoids the issue that this is wrong to start with. Consider this. Spreadsheets almost invariably contain anniversaries of fixed dates - someone's birthday, the date of a battle, the time/date of an appointment, whatever. These are independent of TZ. If your birthday is 6th July 1960 in Belgium, then it's also 6th July if you happen to live in California. If you were born at 00:30AM, your passport still shows 6th July, even though that time was actually 5th July in CET and PDT. For an anniversary, or an appointment, no-one gives a damn about timezones. In a spreadsheet, only a tiny proportion of users care about TZ's. I can't immediately think of a single use-case where it actually matters.
Lotus 1-2-3 got this right. Excel got this right. A date is an integer serial number, with no time zone information. Copy a date from one spreadsheet to another, it's always right. Get a date from a spreadsheet using VB/whatever, put it in another spreadsheet, it's always right (I think). Much as I hate to say it, Excel defines spreadsheets, and they do it Good. Apart from VB.
In GAS, if I copy a date using getValues, it's wrong. Google have over-smarted this. Ok, there is a complex work-around that involves finding what TZ your spreadsheet was created in, assuming that the date you entered was actually an epoch date relative to UTC, and displaying it according to the spreadsheet's current TZ setting (at least, I think that's what you're doing). But so what? And, does it always work? What if you mail the spreadsheet to someone who lives in PDT? I'm sure you can get it to work, but that misses the point - this is just a work-around, which I think might be fragile (note that there are 3 TZ settings: the Google account setting, the sheet setting, and the script setting, and you have to take account of all of them - see ahab's post here). The fundamental issue is that Google spreadsheets store dates relative to a specific TZ (is the underlying format ms relative to Unix epoch??). This was just wrong, and is now unfixable, and is only one part of a large can of worms to do with date handling.
As a short-term fix, I can probably add 12 hours to all dates in a spreadsheet. As a longer-term fix, I should probably handle all dates as text strings and do it myself in JavaScript. I've already had to replace all elapsed times with "integral" number of milliseconds to handle the issues to do with lost milliseconds in GAS dates. Go on, convince me I'm wrong.
EDIT by Serge :
Hi, I took the liberty to answer in your edit for ease of reading (sorry about that).
I do understand your point of view but I don't share it.
The UI example you refer to needs indeed a workaround because this is pure javascript, not spreadsheet date ... That said, Excel spreadsheets and Google spreadsheets work the same way (next day is day+1, time = decimals and ref date 0 = 12/31/1899)) as long as you stay in the spreadsheet universe, the problem comes when you quit the spreadsheet and go to Javascript (ref date = 01/01/1970, count in milliSecs)...
If they had chosen not to care about TZ and keep dates 'static' across any time zone it would have had a lot of other issues : for example what if you want to setup an appointment on skype between me in Belgium and President Obama in Washington ? If we decide to have that conversation on monday at 8 AM will it be 8 AM in Belgium or in Washington ?
With the Google solution he will just have to wake up a bit early but we will both be there since the date and time would show the same 'moment', with the way you suggest there won't be any chance we talk to each other (how sad that would be^^) .
There are a lot more situation where it is obviously a better choice : communication with Calendar service is also a good example.
The static excel solution works nicely because such a document isn't shared the same way and doesn't convert dates to Javascript date Objects. An Excel SS is related to the computer's user, a Google SS keeps this relation to the user's computer using the Time Zone setting because it is (by nature) not related to user's computer.
I have little hope to convince you (;-) but I hope this will at least make things a bit clearer... (and anyway I'm not a Google engineer and have no way to influence them in any way ^^).
one more EDIT...
Here is a small test sheet with TZ settings set to GMT-8 that gets the value of the other test sheet (set to GMT+2 Belgian winter time) and shows it the right way by using this simple script :
function timeCorrection() {
var thisSheet = SpreadsheetApp.getActiveSheet();
var otherSS = SpreadsheetApp.openById('0AnqSFd3iikE3dENrc2h1M0ktQTlSNWpNUi1TS0lrNlE');
var otherSheet = otherSS.getSheetByName('Sheet1');
var otherValue = otherSheet.getRange(1,1).getValue();
var tz = otherSS.getSpreadsheetTimeZone();
var thisSheetValue = new Date(Utilities.formatDate(otherValue,tz,'MM/dd/yyyy HH:mm:ss'));
thisSheet.getRange(1,1).setValue(thisSheetValue);
}
As simple as that ;-) , settings of the 'foreign sheet' are set to the same value as its script settings which is default for a newly created sheet created in Vancouver.
This is not a bug...
May I offer another solution to the problem that is less programmatic? I isolated this issue and spend a day trying to figure out why my script was pulling dates with a previous day and 23:00PM.
Then, I realized that Spreadsheet is not a comma separated database but has its auto-formatting. So, the problem is solved when in Spreadsheet I selected my column containing dates and from menu chose Format>Numbers>Plain Text. Now my script runs perfect without tons of way around. Applying this to an entire column affects even a newly added cells. So its a sweet solution.
Since this is stackoverflow, here is the java solution (I check it works):
sheet.getRange(1,n).setNumberFormat('#STRING#');
I took it from christian.simms, from here:
Format a Google Sheets cell in plaintext via Apps Script
The main problem is incorrect time zone for a date object.
So I not found way to get a string from a cell if it has date type. The cell will return representation based on the time zone but it is not the same as on local computer, so you can get date ± one day.
You can get the time zone for the current account:
var userTimeZone = CalendarApp.getDefaultCalendar().getTimeZone();
Warning! This is not time zone of local computer, so this is another problem.
So you can get correct string of the date:
var date1 = SpreadsheetApp.getActiveSheet().getRange(1, 1).getValue();
var str = date1.toLocaleString("en-US", {timeZone: userTimeZone });

How to get the current TimeStamp?

I'm trying to get the current time as TimeStamp without success.
I have this code:
QDateTime setTime = QDateTime::fromString (QString("1970-07-18T14:15:09"), Qt::ISODate);
QDateTime current = QDateTime::currentDateTime();
uint msecs = setTime.time().msecsTo(current.time());
return QString::number(msecs);
The output is
Sunday, January 25th 1970, 03:17:35 (GMT)
In Qt 4.7, there is the QDateTime::currentMSecsSinceEpoch() static function, which does exactly what you need, without any intermediary steps. Hence I'd recommend that for projects using Qt 4.7 or newer.
I think you are looking for this function:
http://doc.qt.io/qt-5/qdatetime.html#toTime_t
uint QDateTime::toTime_t () const
Returns the datetime as the number of seconds that have passed since 1970-01-01T00:00:00, > Coordinated Universal Time (Qt::UTC).
On systems that do not support time zones, this function will behave as if local time were Qt::UTC.
See also setTime_t().
Since Qt 5.8, we now have QDateTime::currentSecsSinceEpoch() to deliver the seconds directly, a.k.a. as real Unix timestamp. So, no need to divide the result by 1000 to get seconds anymore.
Credits: also posted as comment to this answer. However, I think it is easier to find if it is a separate answer.

Resources