This code gives you tomorrow after midday - vba

Consider this:
Dim n as Long
n = Now
Why does this give you tomorrow after midday?

It's because Now returns a double to represent the time of day as well as the day itself. The fractional part is used to model the time of day and at noon that value is exactly one half.
Also, the implicit cast to Long rounds the value. This is unlike the casts of c and c++ which truncate the fractional part.
You could use Fix(Now) to truncate.

Related

What do I have to change in my syntax for it to work in MS SQL Server from Informix

I'm currently updating a lot of our queries to work again in our new ERP-Release, where we will be working with MS SQL Server, swapping away from our current Informix database. Many are just simple Date-Format changes but this one I am unable to translate.
It really only is the following line:
round((GETDATE() - max(l105.dataen))::interval second(9) to second::char(10)::int
/ 60 / 60, 3)
I simply can't grasp what the part starting at the colons (::) is doing or what function it is.
I hope someone maybe can identify it.
In Informix, subtracting two DATETIME values results in an INTERVAL. The <value>::<type> notation is a shorthand for CAST(<value> AS <type>). Therefore, there are three consecutive casts:
::interval second(9) to second
::char(10)
::int
By default, if you subtract two DATETIME YEAR TO SECOND values, you will get an INTERVAL DAY(n) TO SECOND value. The first cast converts that to INTERVAL SECOND(9) TO SECOND — a number of seconds; the second cast converts the result to CHAR(10) because there isn't a direct conversion from INTERVAL to numeric types; the third cast converts the string to an INT. That gives the integer number of seconds; it is divided by 60 twice (effectively, divided by 3600) to convert the seconds into hours.
The result is then rounded to 3 decimal places.
So, the overall operation calculates the number of hours between two times.
The two times are the current time and the most recent value in the l105.dataen column (the MAX expression). Presumably, there is a GROUP BY clause somewhere in the SELECT statement that this is a part of.
You will likely need to use a 'time difference' function in MS SQL Server, and maybe the function allows you to control the presentation of the result as a number of hours and fractions of an hour.
Judging from DATEDIFF function, you will need to use something like:
DATEDIFF(hh, MAX(l105.dataen), GETDATE())
However, that returns an integer value for the difference in hours. You may prefer to get the time in seconds and divide by 3600 to get a fractional value:
DATEDIFF(ss, MAX(l105.dataen), GETDATE()) / 3600.0
No database server was consulted to ensure the veracity of the suggested translation.

Does BigQuery support nanoseconds in any of its date time data type?

I have done some research on DATETIME and TIMESTAMP data type and I understand that they support date time to be represented in milliseconds and microseconds
like the one below,
YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDD]]
But, is it possible to load/represent values that has nanoseconds precision?
like,
YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDDDDD]]
Actually, BigQuery supports up to microsecond precision, and not only millisecond.
No, I don't believe it supports nanosecond precision (maybe a Googler will correct me there), and I certainly can't see anything in the docs. However, this is stated:
An error is produced if the string_expression is invalid, has more
than six subsecond digits (i.e. precision greater than microseconds),
or represents a time outside of the supported timestamp range.
Thus, this will work:
SELECT CAST('2017-01-01 00:00:00.000000' AS TIMESTAMP)
But this will not ("Could not cast literal "2017-01-01 00:00:00.000000000" to type TIMESTAMP"):
SELECT CAST('2017-01-01 00:00:00.000000000' AS TIMESTAMP)
For more context on timestamp precision, consider the supported range of BigQuery timestamps, which is 0001-01-01 00:00:00.000000 to 9999-12-31 23:59:59.999999. With microsecond precision, if you anchor timestamps to the Unix epoch, this means that you can represent the start of this range with the integer value -62135596800000000 and the end with 253402300799999999 (these are the values that you get if you apply the UNIX_MICROS function to the timestamps above).
Now suppose that we wanted nanosecond precision, but we still wanted to be able to express the timestamp as an integer relative to the Unix epoch. The minimum and maximum timestamps would be represented as -62135596800000000000 and 253402300799999999. Looking at the range of int64, though, we would need a wider integer type, since the min and max of int64 are -9223372036854775808 and 9223372036854775807. Alternatively, we would need to restrict the range of timestamps to approximately 1677-09-21 00:12:43 to 2262-04-11 23:47:16, assuming I did the math correctly. Given that nanosecond precision generally isn't that useful, having the wider timestamp range while still being able to use a 64-bit representation is the best compromise.

Convert TIMESTAMPL (timestamp long) to TIMESTAMP ends with 60

I am having an OData Service returning some DateTime values. They are saved in a table in the back end as TIMESTAMPL (with some other data).
Now there is the value 20160630084459.5000. With MOVE-CORRESPONDING into the et_entityset, where it is a TIMESTAMP. Because of the rounding, it gets 20160630084460, Since a the seconds must be between 00 and 59, this is not a valid value to return.
My main problem is, that my table has extremely much entries, so I need a performant way to fix this error.
Here is a way to convert it to what you want.
REPORT zzy NO STANDARD PAGE HEADING.
FORM convert_timestamp.
DATA(l_t1) = CONV timestampl('20160630084459.5000').
DATA: l_t2 TYPE timestamp.
l_t2 = l_t1.
WRITE / : l_t1, l_t2.
CONVERT TIME STAMP l_t1 TIME ZONE sy-zonlo INTO DATE DATA(l_date) TIME DATA(l_time).
CONVERT DATE l_date TIME l_time INTO TIME STAMP l_t2 TIME ZONE sy-zonlo.
WRITE / l_t2.
ENDFORM.
START-OF-SELECTION.
PERFORM convert_timestamp.
Here is the output.
20.160.630.084.459,5000000
20.160.630.084.460
20.160.630.084.459
You mention floor in your question but that is not what is happening. The value is rounded. If you simple do use FLOOR in your assignment from TIMESTAMPL to TIMESTAMP you will get the answer you want. If you have to use MOVE-CORRESPONDING, just do that first and then do a seperate assignment for the timestamp.
However, this means that 0:59.9 will get translated to 0:59 and not 1:00. If that missing second is OK for your application then just use the FLOOR command. If not it becomes more complicated and you will take a performance hit.

Convert time from seconds to hours, with rounding

I need to convert time from seconds to hours with 2 decimal rounding
PeriodLength contains time in seconds.
(c.PeriodLength)/3600. as Time
Returns time in hours but result is like 1.250000
and I need it to be 1.25.
Using standard SQL, you can convert it to a decimal. Something like:
select cast(c.PeriodLength / (60.00*60) as decimal(6, 2));
There are also database specific solutions, but you don't specify the database.
SET value = ROUND(value,2)
Note that this is generally used for statistical purposes, rather than monetary or time. However, it should work for what you are seeking.

VB.Net 2005, how can I subtract a date from the (current date minus 7 days) and produce a number of days?

I have a date in the future e.g. 13/10/2008 I need to subtract the current date (today is the 28/09/2010) minus 7 days, so thats 21/09/2010 minus 13/10/2008, which would equal erm, 720 something ?
But the current date won't always be 28/09/2010, obviously.
I need the code for this.
EDIT: When i said future I mean past :)
Sub Main()
Dim dt As DateTime = New DateTime(2008, 10, 13)
' be careful what you are subtracting from what
' the date you have is not in the future (year 2008)
' if the date is in the future: (dt.Subtract(DateTime.Now.AddDays(-7))).TotalDays
' or simply take the absolute value
Dim days As Double = (DateTime.Now.AddDays(-7).Subtract(dt)).TotalDays
Console.WriteLine(days)
End Sub
You will also notice that the TotalDays property is of type Double.
13/10/2008 is not exactly in the future :)
Sorry for using C# code, but:
(dateInFuture - DateTime.Now.AddDays(-7)).TotalDays
Should work. Of course the other way around if you mean in the past:
(DateTime.Now.AddDays(-7) - dateInPast).TotalDays
Dim ValidDate As Date =cDate("Tuesday, December 31, 2013") 'A date in Future
Dim date1 As New System.DateTime(ValidDate.Year, ValidDate.Month, ValidDate.Day)
Dim date2 = Now
Dim Diff1 As System.TimeSpan
Diff1 = date1.Subtract(date2)
Dim TotRemDays = (Int(Diff1.TotalDays))
MsgBox(TotRemDays)
"I need the code for this" seems a bit too much like "Plz give meh teh codez", and your "date in the future" seems a little bit in the past.
Anyway, you should investigate the relevant methods of the DateTime structure, in particular the Subtract method (both overloads, or in alternative its subtraction operator), and you should have a look at the TimeSpan structure too.
You could create a DateTime for the date of today, subtract a TimeSpan of 7 days to it, and then subtract such result to a DateTime representing your date in the future (or, if it is in the past, do the opposite). You'll get a TimeSpan representing the difference in time between the two dates, from which you can easily get the number of days using its Days property.
As other said, to do the first subtraction you can also use the AddDays method of the DateTime structure.