Comparing date/time values in microsoft access 2010 - ms-access-2010

I am having some trouble comparing date/time values in Microsoft Access.
I am currently using the query below to get all the absence records for the day. I have no issues when it is a plain date value but records with time included cannot be retrieved with the query.
SELECT * FROM table_name
WHERE [Start Date/Time] <= Date() AND [End Date/Time] >= Date()
I have a table used to store absence records of the following form.
Name: Text
Start Date/Time: Date/Time
End Date/Time: Date/Time

You can for example use:
SELECT * FROM table_name
WHERE Fix([Start Date/Time]) <= Date() AND Fix([End Date/Time]) >= Date()
to remove the time part, or:
SELECT * FROM table_name
WHERE DateDiff("d", [Start Date/Time], Date()) >= 0 AND DateDiff("d", [End Date/Time], Date()) <= 0
to ignore the time part.

Related

Lazarus SQLite date entry displays improperly

UPDATE: Issue was solved by #whosrdaddy. See comments below this question.
I am trying to resolve the following peculiar case: In a friend's Lazarus project, he tries to query an entry in SQLite. The asString()-method (in the procedure for displaying appointments) returns the proper date on Windows 64 Bit. On a 32 Bit operating system, however, only the first two digits are displayed ('16' instead of '28.02.2016'). What could be the reason?
This is the source code for initialising the form:
// Initialise Form
procedure TForm1.FormCreate(Sender: TObject);
begin
SQLite3Connection1.DatabaseName:='Kalender.sqlite';
SQLTransaction1.Database:=SQLite3Connection1;
SQLQuery1.Transaction:=SQLTransaction1;
// Create Table "tblTermine"
SQLQuery1.SQL.text := 'CREATE TABLE IF NOT EXISTS tblKalender (Datum DATETIME, Termin VARCHAR(10))';
SQLQuery1.ExecSQL;
SQLTransaction1.commit;
end;
There are two further procedures:
// Display Appointments
procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Clear;
SQLQuery1.Close;
SQLQuery1.SQL.text:='SELECT * FROM tblKalender';
SQLQuery1.Open;
while not SQLQuery1.Eof do
begin
// Should return 'dd.mm.yyyy'
ListBox1.Items.add(SQLQuery1.Fields[0].AsString+ ': ' + SQLQuery1.Fields[1].AsString);
SQLQuery1.Next;
end;
end;
// Save Appointment
procedure TForm1.Button2Click(Sender: TObject);
var Termin: string;
Datum: TDate;
begin
Termin:=Edit1.text;
if calendardialog1.execute then
Datum:=TDate(calendardialog1.date);
SQLQUERY1.close;
SqlQuery1.SQL.text:= 'Insert into tblKalender Values (:Datum, :Termin)';
SqlQuery1.ParamByName('Datum').AsDate:= Datum;
SqlQuery1.ParamByName('Termin').AsString:= Termin;
SqlQuery1.ExecSQL;
SqlTransaction1.Commit;
Button1.Click;
Edit1.Text := '';
end;
The intended output into the TListBox would be something like this.
you should convert first the DateTime to a Julian Date
function DateTimeToJulianDate(const Datum: TDateTime): Double;
and
SqlQuery1.SQL.text:= 'Insert into tblKalender Values (:Datum, :Termin)';
SqlQuery1.ParamByName('Datum').AsFloat := DateTimeToJulianDate(Datum);
...
SqlQuery1.ExecSQL;
to test and get the value use :
function TryJulianDateToDateTime(const AValue: Double; ADateTime: TDateTime):Boolean;
if TryJulianDateToDateTime(SQLQuery1.Fields[0].AsFloat,myDate)
then
ListBox1.Items.add(DateTimeToStr(myDate)+ ': ' + .....
else
ShowMessage('Not a valid Julian date');
Update
SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic
Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Double Test
procedure TForm1.Button3Click(Sender: TObject);
var
Datum : TDate;
myDate : TDateTime;
JulianDouble : Double;
begin
// uses ....,DateUtils
Datum := StrToDate('01.01.2013'); //German Culture settings
Memo1.Lines.Add('01/01/2013 = '+DateTimeToStr(Datum)+ ' TDate as Text');
Memo1.Lines.Add('01/01/2013 = '+FloatToStr(Datum) + ' TDate Double');
JulianDouble := DateTimeToJulianDate(Datum);
Memo1.Lines.Add('01/01/2013 = '+FloatToStr(JulianDouble) + ' Julian Double');
if TryJulianDateToDateTime(JulianDouble,myDate)
then
Memo1.Lines.Add('01/01/2013 = '+DateTimeToStr(myDate)+ ' TDate as Text')
else
ShowMessage('Not a valid Julian date');
end;
Output :
01/01/2013 = 01.01.2013 TDate as Text
01/01/2013 = 41275 TDate Double
01/01/2013 = 2456293,5 Julian Double
01/01/2013 = 01.01.2013 TDate as Text
Update-2 :
To write Delphi TDate Double to a SQLite Date field is wrong
Your comment shows me that you do not know the problems.
Of course you can directly write a Delphi Double value into a database field. And read it back to a TDateTime.
This will quickly lead to problems.
Examples:
SQLite:
These functions only work for dates between 0000-01-01 00:00:00 and
9999-12-31 23:59:59 (julidan day numbers 1721059.5 through 5373484.5).
For dates outside that range, the results of these functions are
undefined.
41275 Delphi TDate Double for 2013/01/01 is outside of above range !!
SQLite's own date functions can no longer be used.
Compute the current date.
SELECT date('now');
Compute the last day of the current month.
SELECT date('now','start of month','+1 month','-1 day');
Compute the date and time given a unix timestamp 1092941466.
SELECT datetime(1092941466, 'unixepoch');
Compute the date and time given a unix timestamp 1092941466, and compensate for your local timezone
SELECT datetime(1092941466, 'unixepoch', 'localtime');
Compute the number of days since the signing of the US Declaration of Independence.
SELECT julianday('now') - julianday('1776-07-04');
etc. etc.
Changing the date value with above functions will give you a double 2456293,5 for a Date 2013/01/01
If you now use unproved and pass it to a Delphi TDateTime it will be 3387/11/26).
This is not far from the maximum value of a TDateTimePicker.
which is 2958465.5 and means 9999/12/31
DateTimePicker1.DateTime := 2958465.5;
DateTimePicker1 9999/12/31
If one already know that it is wrong one should not use it up to a crash.
SQLite uses something called manifest typing which means that if you store values of (Delphi) type TDateTime, SQLite will store the underlying floating point value without warning or message, and offer you the value back so you won't notice that SQLite doesn't treat this as a date-time-value, unless you're trying to manipulate the value from SQL.
To counteract this, I use this bit of SQL code to convert Delphi TDateTime values to an actual SQL datetime:
datetime('1900-01-01','+'||(myDateField-2)||' day')
(see also here)

Select from SQLite database if entry is from 'today'.Timestamp is GMT but SELECT should be timezone specific

I have a list of tasks stored in an SQLite database with timestamp in GMT format as follows:
Timestamp: 2014-07-10 00:42:43
I am trying to get all 'todays tasks' but 'today' relevant to the timezone. (so the above Timestamp example in Eastern Standard time is actually a task from the July 9th not the 10th
My query:
"SELECT * FROM " + TABLE_TASKS + " WHERE date('timestamp','localtime') >= date('now', 'start of day','localtime')"
Doesn't select the tasks when the GMT time has rolled over to the next day even though in EST it is still july 9th.
why is this happening?
> create table t(timestamp);
> insert into t values (datetime('now'));
> select date('timestamp') from t;
> select date("timestamp") from t;
2014-07-10
> select date(timestamp) from t;
2014-07-10
In SQL, anything enclosed in single quotes is a string, and timestamp is not a date/time value in one of the supported formats.
If you wanted to quote an identifer (i.e., a table or column name), you would need to use double quotes.
However, timestamp is not a keyword, so you don't need to quote it at all.

How to compare Starting time and End time of a event with existing events of same time on same day?

I am using MS SQL server 2008. Here I need to compare the newly entered start time and End time of an event with the existing event timings. In the Database I need to check the new Starting time and End time values and the time Period should not match with the existing/ already booked event timings.
I need to check this condition in the Database stored procedure, if the condition is satisfied then only accept the event. Best example is Conference hall booking.
SELECT #count = COUNT (EventID) FROM TblEvent WHERE (('#STARTTIME' BETWEEN StartTime AND EndTime) or ('#ENDTIME' BETWEEN StartTime AND EndTime));
IF #count = 0
Begin
Select #count = COUNT (EventID) FROM TblEvent WHERE (('#STARTTIME' < StartTime and '#ENDTIME' > EndTime));
END
IF #count > 0
BEGIN
SELECT 'Event is Already Exists at that point of time please select another Time ' AS 'MESSAGE';
END
Else
BEGIN
//ADD QUERY TO SAVE THE THE EVENT IN DB//
SELECT 'Event is Added' AS 'MESSAGE';
END
NOTE:
#STARTTIME = USER ENTERED START TIME,
#ENDTIME =USER ENTERED END TIME
You can use 24 hour format to solve this in your logic. you have to save existing event timings in Database. whenever new event timings entered, you need to compare with existing both start & end timings with previous ones.
For Example:
Event1: x1 to y1
Event2; x2 to y2
if(x2==x1 && y2==y1)
if(x2>x1 &&x2<y1) andif(y2<y1)
...so on based on your requirement.
Answer is (StartA <= EndB) and (EndA >= StartB). Please, read these: Determine Whether Two Date Ranges Overlap
Hey Sanjeev try the following code..!
Select * From your Event
WHERE ('A' BETWEEN StartTime AND EndTime) or ('B' BETWEEN StartTime AND EndTime)
Note:
Here A and B are your Start time and End Time,
and Italics are your database values.
If I had understood correctly, this should solve the problem.
Let us take A and B are your start time. X and Y are previously in Database.
Then (A,B) does not over lap (X,Y) when X > B or Y < A this can be told as the new event must finish before the previous one or it must start after the previously available one. So query must be
...
Where NewStartTime > EndTime or NewEndTime < StartTime;

ASP.Net SQL Where Date is after Today

Hi all I have the following Query made using the Query Builder in Visual Studio.
SELECT Schd_ID, Schd_Date, Schd_Avaliable, Schd_Nights, Schd_Price, Accom_ID
FROM Schedule
WHERE (Schd_Avaliable = 'Yes') AND (Accom_ID = Accom_ID)
I want to add another WHERE statement which adds where Schd_Date is after todays date, any ideas?
Assuming SQL Server, the GETDATE() function returns the date and time the statement was run at:
WHERE Schd_Date > GETDATE()
Use the following for finding dates greater than the current date at midnight:
WHERE Schd_Date > DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
However, CURRENT_TIMESTAMP is the ANSI means of getting the current date and time in a database. Beyond that, date functionality is not consistent between databases so you'd have to tell us what you are dealing with for better answers.
If this is SQL Server you could use the GETDATE() function to return the current date and compare against it:
SELECT
Schd_ID, Schd_Date, Schd_Avaliable, Schd_Nights, Schd_Price, Accom_ID
FROM
Schedule
WHERE
(Schd_Avaliable = 'Yes')
AND
(Accom_ID = Accom_ID)
AND
(Schd_Date > GETDATE())
SELECT Schd_ID, Schd_Date, Schd_Avaliable, Schd_Nights, Schd_Price, Accom_ID
FROM Schedule
WHERE (Schd_Avaliable = 'Yes') AND (Accom_ID = Accom_ID) AND (GETDATE() < Schd_Date)
This should work
I guess this expression can be used as a date representing the current date on the format yyyy-mm-dd (without the hours,minutes and seconds).
(Datepart('yyyy',getdate())+ '-' +Datepart('m',getdate())+ '-' + Datepart('d',getdate()))
therefore
SELECT Schd_ID, Schd_Date, Schd_Avaliable, Schd_Nights, Schd_Price, Accom_ID
FROM Schedule
WHERE (Schd_Avaliable = 'Yes') AND (Accom_ID = Accom_ID) AND
(Schd_Date >= (Datepart('yyyy',getdate())+ '-' +
Datepart('m',getdate())+ '-' +
Datepart('d',getdate())))

Query to check Date in Sql

My query is simple yet bit twisted for me. Actually I am working on registration module of an app, where the registration expires 31st March every year. The registration is valid from April 1 to March 31. So whenever a user is registered in between the date, I want his status to be expired if march 31 is crossed.
Let me make more clear to you.
Say I have registered my self in 15Nov2010, then on 31st March 2011, my subscription will get expired. I want to check it automatically as the years will go on. I need a query that will automatically query the created date with expiration date. I am already having a select query and i need to embed this condition and i want to check the creation date with current system date. If Current system date is not 31 march midnight 12, the status must be active else expired.
This can be used for MS SQL to determine whether it has expired or not.
create table #t
(
CreateDate datetime
)
Insert Into #t
select GETDATE() union all
Select DateAdd(month,4, getdate())
Select Case When CreateDate < getdate() And
Getdate() < Cast(str(DatePart(year, getdate())) + '-03-31' as datetime) Then
'Active' Else 'Expired' end as [Status],
CreateDate
From #t
drop table #t
To filter your query you would simply move the case statement to a where clause
e.g.
Where Case When CreateDate < getdate() And
Getdate() < Cast(str(DatePart(year, getdate())) + '-03-31' as datetime) Then
'Active' Else 'Expired' end = 'Expired'
What you need is to schedule a job (i think they're called events on MySql) to run every year on March 31 11:59 and update set the status of all your accounts to expired. (remember to make dstinction on admin accounts) :)
Take a look at this.
for MySQL
http://dev.mysql.com/tech-resources/articles/mysql-events.html#1
for SqlServer
http://msdn.microsoft.com/en-us/library/ms191439.aspx
http://msdn.microsoft.com/en-us/library/ms190268.aspx
I am considering a table YourTable and it has a column Date of type datetime
You can use this query -
select [Date], dbo.GetStatus([Date]) as 'status' from YourTable
And, the function GetStatus -
CREATE FUNCTION [dbo].[GetStatus](#Date datetime)
RETURNS varchar(10)
AS
BEGIN
DECLARE #Return varchar(10)
DECLARE #Year int
SELECT #Year = DATEPART(YYYY,GETDATE())
IF GETDATE() >= CONVERT(datetime,'01-APR-' + CONVERT(varchar,#Year))
SET #Year = #Year + 1
IF #Date BETWEEN CONVERT(datetime,'01-APR-' + CONVERT(varchar,#Year-1)) AND CONVERT(datetime,'31-MAR-' + CONVERT(varchar,#Year))
set #return = 'active'
ELSE
set #return = 'inactive'
Return #return
END;
I'd probably have a "last renewed" column (It would initially store the creation date) then write:
SELECT CASE WHEN
YEAR(DATEADD(mm, -3, LastRenewed)) < (YEAR(GETDATE()) - 1)
THEN 'Active'
ELSE 'Expired' END
AS Status
FROM TableName
I don't see what the problem with #Barry's answer is though, to be honest. If you need to use this logic in several places you can avoid repeating yourself using a view eg:
CREATE VIEW ActiveOrNot AS
SELECT Account, CASE WHEN
YEAR(DATEADD(mm, -3, LastRenewed)) < (YEAR(GETDATE()) - 1)
THEN 'Active'
ELSE 'Expired' END
AS Status
FROM TableName
You could then select only active accounts using:
SELECT Account
FROM ActiveOrNot
WHERE Status = 'Active'

Resources