Use same DateTime for entire select statement - tsql

I inherited some code that looks like this:
update hm
set hm.status = '130'
,hm.updatedtimestr = convert(varchar,getdate(),101) + ' ' + convert(varchar,getdate(),108)
from homemain hm
where cast(hm.ExpireTime as DATE) < GETDATE()
and hm.Status = '100'
;
This has the classic problem of calling a time routine multiple times in a single routine that if the clock ticks from just before midnight to just after midnight between GETDATE() calls undesirable things will happen in the code. Specifically, updatetimestr could be set to 24 hours prior to the actual time.
I can add a
declare #mynow datetime;
set #mynow = GETDATE()
and use #mynow instead of GETDATE(), but I would rather use something built into tsql that is defined as returning the same time for the entire execution.
Is there a variation of GETDATE() that will return the same time for the entire execution of the statement? Perhaps statement start time?
Please ignore that the previous developer storing a datetime in a string; it is not my doing and I am systematically refactoring that kind of crud out of the system.

Try to use FORMAT (starting with 2012):
SELECT FORMAT(GETDATE(),'MM/dd/yyyy HH:mm:ss')

Related

wrong date when i change int time with FROM_UNIXTIME

I have a old database that i want to transfer, but i have some trouble with my column dateP(int). I got a wrong datetime.
In my old script, I enter the date-time like this:
$date_created = time();
$data_insert = "INSERT TO table $date_created, $title";
Now I have the column datePub (int) that I convert to time stamp format,
For resolve this problem i make this.
UPDATE `table ` SET `date_created` = FROM_UNIXTIME(`datePub `)
But I got a wrong date when I make this date('M d, Y', $PuDate);
I put the right specifier in date_format and its good now.

Noda Time Date Comparison

I am new to Noda Time and I basically want to compare if a date has expired or not. In my case I have an object with the date it was created, represented by a LocalDate and the amount of months it's valid as an int, so I wanted to do a simple:
if ( Now > (dateCreated + validMonths) ) expired = true;
But I can't find in the Noda Time documentation the proper way to get the Now Date (they only show how to get the Now Time as SystemClock.Instance.Now) and the proper way to handle time comparisons.
For example if today is January 1st 2015 and the document was created in December 1st 2014, and it was valid for one month, today it expires its one month validity.
I miss methods such as isBefore() and isAfter() to compare dates and times. Simple overloads of the < > operators could also be very helpful.
EDIT:
1 - Sorry, there are < > operators to compare dates.
2 - I solve my problem using this code (not tested yet!):
...
LocalDate dateNow = this.clock.Now.InZone(DateTimeZoneProviders.Tzdb.GetSystemDefault()).LocalDateTime.Date;
LocalDate dateExpiration = DataASO.PlusMonths(validity);
return (dateNow < dateExpiration);
To get the current date, you need to specify which time zone you're in. So given a clock and a time zone, you'd use:
LocalDate today = clock.Now.InZone(zone).Date;
While you can use SystemClock.Instance, it's generally better to inject an IClock into your code, so you can test it easily.
Note that in Noda Time 2.0 this will be simpler, using ZonedClock, where it will just be:
LocalDate today = zonedClock.GetCurrentDate();
... but of course you'll need to create a ZonedClock by combining an IClock and a DateTimeZone. The fundamentals are still the same, it's just a bit more convenient if you're using the same zone in multiple places. For example:
// These are IClock extension methods...
ZonedClock zonedClock = SystemClock.Instance.InTzdbSystemDefaultZone();
// Or...
ZonedClock zonedClock = SystemClock.Instance.InZone(specificZone);

Date display Appery.io

I use a date picker that saves the date in a yyyy-mm-dd format in a database. It then automatically adds time that always appears as 00:00:00. So for example it displays the date like this : 2014-12-14 00:00:00. I want it to display just the date in a mm-dd-yyyy format.
I use the code below but something seems to be wrong with it because it simply doesn't change the way it is displayed. I want to split up each of the values, then display only the date in a different format.
var parts = value.split("/");
return parts[1] + "-" +parts[2] + "-" +parts[0];
What can I do to make it work? Javascript please.
Thanks in advance.
It's a wide variety of solutions. Depends on you server-side settings too, but I will assume, that you use common for most websites MySQL DB and PHP.
You can change you column type to DATE. As said in docs:
The DATE type is used for values with a date part but no time part.
MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The
supported range is '1000-01-01' to '9999-12-31'.
You can change your column type to VARCHAR and store a date in any format you like when INSERT it
You can convert it to proper format using MySQL built-in DATE_FORMAT()
SELECT DATE_FORMAT('2014-12-14 00:00:00', '%c-%e-%Y');
will give you 12-14-2014. Here is sqlfiddle,
just change first param to your column name in query
On server you can use PHP's date() function like this
$yourdate = '2014-12-14 00:00:00';
echo date("m-d-Y", strtotime($yourdate));
Closer to your question, how to do it in JS? It also has special object for this: Date(). Put your date in constructor, then use methods:
var yourdate = new Date('2014-12-14 00:00:00');
alert(yourdate.getMonth() + "-" + yourdate.getDate() + "-" + yourdate.getFullYear());
JSFiddle < - here
So, as far as almost every platform understands this datetime format - you can use any tool for converting it

Problems with query using timespan

I am doing a manual query to my postgresql database (using OrmLiteReadConnectionExtensions.SqlList<T>) that has a TimeSpan argument.
SericeStack.Ormlite is converting TimeSpan to ::time instead of ::interval as I would expect it.
More specifically: TimeSpan.FromDays(3) is converted to ((E'00:00:00.000000')::time)(taken form pg logs).
Is there a work around for this?
My current work-around is to use the C# string.Format for this problematic parameter instead of the safe and recommended™ #paramname supported by SqlList<T>.
This could be considered dangerous, but since the parameter is a double, I'm probably Okay.
The relevant part of the string is:
string.Format(CultureInfo.InvariantCulture, "RESTOFTHEQUERY ('{0:0.####} seconds'::interval) RESTOFTHEQUERY", timespan.TotalSeconds);
Don't forget to use CultureInfo.InvariantCulture.
For what it's worth, you can just cast a time value to interval. Demo
SELECT now()::time::interval
So append ::interval in your manual query and you should be fine - except for intervals > 24 hours of course.

How to change a cell's code after it's been moved in Excel using VBA

I have an Excel VBA Script I've written with help, I am not a neophyte when it comes to coding, but to me so far Excel VBA has been an arsenic nightmare wrapped in a sugar pill sold by MS as a language easy to learn.
Ok, rant out of the way sorry, but I digress.
Here is the complete script:
Option Explicit
Sub tgr()
Dim wsB As Worksheet 'BackOrder
Dim wsJ As Worksheet 'Jobs List
Dim wsA As Worksheet 'Archive
Dim LastRow As Long
Set wsB = Sheets("BackOrder")
Set wsJ = Sheets("Jobs List")
Set wsA = Sheets("Archive")
With Application
.ScreenUpdating = False
.DisplayAlerts = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
With Intersect(wsJ.UsedRange, wsJ.Columns("N"))
.AutoFilter 1, "<>Same"
With Intersect(.Offset(2).EntireRow, .Parent.Range("B:L"))
.Copy wsA.Cells(Rows.Count, "B").End(xlUp).Offset(1)
.EntireRow.Delete
End With
.AutoFilter
End With
LastRow = wsB.Range("B6").End(xlDown).Row
wsB.Range("P5:Q5").Copy wsB.Range("P6:Q" & LastRow)
Calculate
wsB.UsedRange.Copy Sheets.Add.Range("A1")
With Intersect(ActiveSheet.UsedRange, ActiveSheet.Columns("Q"))
.AutoFilter 1, "<>Different"
.EntireRow.Delete
With .Parent
.AutoFilterMode = False
Intersect(.UsedRange, .Columns("G")).Cut .Range("F1")
Intersect(.UsedRange, .Columns("H")).Cut .Range("G1")
Intersect(.UsedRange, .Columns("L")).Cut .Range("H1")
Intersect(.UsedRange, .Columns("N")).Cut .Range("I1")
Intersect(.UsedRange, .Range("B:J")).Copy wsJ.Cells(Rows.Count, "B").End(xlUp).Offset(1)
.Delete
End With
End With
LastRow = wsJ.Cells(Rows.Count, "B").End(xlUp).Row
wsJ.Range("M1:T1").Copy
wsJ.Range("B3:I" & LastRow).PasteSpecial xlPasteFormats
wsJ.Range("U1:W1").Copy wsJ.Range("J3:L" & LastRow)
wsJ.Range("X1:Y1").Copy wsJ.Range("M3:N" & LastRow)
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Sub
As you can see this is a three page script, BackOrder, Jobs List, and Archive, what I need to do is in Archive. The cells in Columns in J & K use TODAY() as a way to tell the rest of the script when it looks in the cell in column F how many days early or late it is.
Column J shows early, Column K shows late.
Column J's script is:
=IF(F3-TODAY()<0,"",F3-TODAY())
Column K's script is:
=IF(TODAY()-F3<1,"",TODAY()-F3)
Column F in this case is part of the larger script, which moves data via an import and has no formatting.
Now, when I bring row into Archive, I want it to be where the cells, instead of having TODAY() in either script, I want it to show the date it was moved over there, so it will still be today, but instead of TODAY(), it will have the date in this format ##/##/##. It will "freeze" the count of J & K so it will be accurate from that day forward, so we will know if it was shipped late, early, or on time.
Is this possible, and if so how?
You are confusing worksheet functions and VBA functions. You stopped your rant too soon although I think Word VBA is the worst version.
With the user interface, I can go to cell A1 and type "4apr12". Excel recognises this as a date, stores the value as 41003 and sets the format to "dd-mmm-yy" which is the standard format closest to what I typed.
Alternately, I could type "41003" then go to the format menu and select or enter a date format of my choice.
Yet another choice is to type "=TODAY()". Excel stores the value as "=TODAY()" but because of the leading equals, it evaluates this as an expression when it is entered and displays the value as a standard date (format dd/mm/yy here in the UK) and re-evaluates the expression when the workbook is opened and saved and when told to do so via the Calculate options.
VBA functions are different. Even when they do the same thing, they often have different names. The nearest equivalent to TODAY() is Now(). This function returns the current date and time as a number. The integer part is the days since 1-Jan-1900; the fraction part is (Number of seconds since midnight)/(Number of seconds in a day). So at midday today, Now() would have returned "41003.5". This is a number; I can multiple it by two, subtract 5000 or whatever.
With VBA, I could execute:
Range("A1").Value = "4apr12"
Excel recognises this as a date just as if I had typed it from the user interface.
Alternatively, I could execute:
Range("A1").Value = 41003.5
This is just a number and will be stored and displayed as 41003.5.
If I want it to be displayed as a date, I must execute:
With Range("A1")
.Value = 41003.5
.NumberFormat = "dd mmm yy"
End With
The value is still saved as 41003.5 but I have told Excel to display it as 4 Apr 12.
I can execute:
Range("A1").Value = "=TODAY()"
This is treated just as if I had typed this formula from the interface.
But suppose I execute:
With Range("A1")
.Value = Now()
.NumberFormat = "dd mmm yy"
End With
Now() returns the current date and time as a number. Excel stores it as a number but displays it as a date because I have told it to. It will never re-evaluate because it is a simple numeric value not an expression involving functions.
I hope you this makes sense and helps you get your mind around the differences between Worksheet functions and VBA functions. Excel and VBA are like learning to drive a car. The first time you KNOW you will NEVER be able to do all these different things at the same time. Yet, a month or two later, you are playing with the pedals, the gear stick, wheel and indicator while checking the mirror. I do not understand why people think patting your head and rubbing your stomach is such as big deal. All I can say is that sudenly the mist will clear and Excel and VBA will make sense.