Get current month as number in Pascal - time

I've got an assignment to do which involves seeing if there are any birthdays this month. I'm not asking for you to 'do my homework', but what I am asking is this: is there a way to get the current month as a number from 1-12 in Pascal (specifically, Lazarus Pascal)? Then I can take the number and compare it with records held in file.
Thanks for any help,
James

I don't know about Lazarus, but most Pascal implementations provide:
procedure GetDate(var Year, Month, Day, DayofWeek: Word);

You can use this code:
DecodeDate(Date:TDateTime, Year, Month, Day: word);
I recommend you to check dateutils unit. It provides full support for all "date" or "time" issues.

Manny is right. I just tried it in Lazarus, by writing this procedure:
procedure Dates;
var y, m, d: word;
begin
DecodeDate(Date, y, m, d);
end;
Date is a function in SysUtils (datih.inc) that returns the current local date. DecodeDate is a procedure that takes a TDateTime and returns to var parameters the calendar values of year. month and day. You need all 3 of course, but just use the one you need.

Related

How to compare dates in a PL/SQL procedure?

I'm a newbie in SQL programming.
I need to make a procedure that will compare dates. The only argument in the procedure is a date typed in by the user in a Java program. I need to check if that argument (date) is before a year ago. In other words, I need to compare it with SYSDATE minus a year. If that is the case, I have to "purge" all of the tables related to "schedules" (there are 2 of them).
So for example, say the user types 2013-04-13, my procedure has to compare it with SYSDATE - 1 year (in that case, it would be 2014-12-03). Since the value is less than today minus a year, the tables "MovieSchedule" and "ChannelSchedule" have to be purged. If the entered date was 2014-12-16, since it's now more than SYSDATE minus a year, the procedure has to send back an explicit error that I will be able to use in the Java program.
Now, as I said I'm completely new to procedure programming in PL/SQL, so here is what I could come up with by looking up tutorials on the internet:
CREATE OR REPLACE
PROCEDURE purge_schedule(purgeDate date) AS
DECLARE
currentDate := to_date(SYSDATE, 'YYYMMDD');
BEGIN
-- IF purgeDate < (currentDate - 1year)
-- delete content in "MovieSchedule" and "ChannelSchedule"
-- ELSE
-- return explicit error
END purge_schedule;
I don't even know if any of this is the right way to write a procedure like I want. And as you can see, my problem is how to implement my condition in the procedure, not the logic behind it. I blame my lack of practice with the language.
Please tell me if I have to be more specific of if you need more information in order to help me. Thank you for your help and have a nice day :)
Step 1, define year. Should be obvious, but is not. I have found month and year definitions vary in the wild. I've seen year defined as 52 weeks, which is never an actual year, and 365 days, which matches one year a little less than 3 of every 4 years, and occasionally 360 days! (30 days / month * 12 months)
sysdate - 365 gives a date 365 days ago.
ADD_MONTHS(sysdate, -12) will give the date 12 months ago. In the case that sysdate is February 29, the result will be February 28 of the prior year.
sysdate - interval '1' year is tempting, but interval year to month arithmetic throws errors when the "result" is a day that is not there.
select date '2012-02-28' - interval '1' year from dual;
02/28/2011
select date '2012-02-29' - interval '1' year from dual;
ORA-01839: date not valid for month specified
It should fill your needs:
IF purgeDate < SYSDATE -365 THEN
...
END IF;
I have illustrated a below working code which help you. Let me know if this helps.
--Compiling the stored proc
CREATE OR REPLACE PROCEDURE purge_schedule(
purgeDate IN DATE )
AS
currentDate DATE:=SYSDATE;
BEGIN
IF purgeDate < ADD_MONTHS(SYSDATE,-12) THEN
DELETE FROM EMP;
DELETE FROM EMP_V1;
dbms_output.put_line('Records purged successfully');
ELSE
RAISE_APPLICATION_ERROR(-20001,'Date provided is not in range deletion not invoked',TRUE);
END IF;
END purge_schedule;
-- Exceuting the proc
set serveroutput on;
exec purge_schedule(to_date('12/12/2013','MM/DD/YYYY'));
-- Output
Records purged successfully
--Executing for negative scenario
set serveroutput on;
exec purge_schedule(TO_DATE('12/12/2017','MM/DD/YYYY'));
--Explicit exception raise
exec purge_schedule(TO_DATE('12/12/2017','MM/DD/YYYY'));
Error report -
ORA-20001: Date provided is not in range deletion not invoked
ORA-06512: at "AVROY.PURGE_SCHEDULE", line 11
ORA-06512: at line 1

Can't understand Oracle job scheduling

I'm currently working on an assignment where I have to port some Oracle scripts to MS SQL. I ran into a problem at the scheduled jobs. The Oracle script looks like this:
dbms_job.submit(job =>v_job,
what =>'begin pkg_report.REFRESH_MVIEWS; end;',
next_date =>Trunc(sysdate, 'HH24')+70/1440, interval =>'Trunc(sysdate, ''HH24'')+70/1440');
dbms_job.submit(job =>v_job, what =>'begin pkg_housekeeping.cleanup_daily; end;', next_date =>trunc(sysdate)+1, interval =>'trunc(sysdate)+1+1/24');
The problem is, I don't understand what this truncing is supposed to do. I tried to replicate it in SQL Developer, played around with it a bit, most of the format strings have very obvoius outcome (YEAR, MONTH, ...), but I don't know what HH24 is supposed to do. And what's with the +70/1440, +1, +1+1/24 suffixes at the end?
I'd appreciate a little help. Thanks in advance!
TRUNC removes the time element of the current date, so the code sets the date to midnight of today (sysdate) and then adds 70/1440 of a day to it.
70/1440 of a day is 01:10 (ten past one in the morning)
+1+1/24 adds one day and 1/24th of a day, so 1am the following day

months_between for a leap year

When I find months between 28-FEB-11 and 29-FEB-12, months_between function in oracle returns 12. Actually it should be 12.096. This function is not calculating for the leap year proper.
For between 28-FEB-11 and 29-FEB-12, it is 1 year(12 months) and 1 day.
select months_between('28-FEB-12', '28-FEB-11') from dual; -- 12
**select months_between('29-FEB-12', '28-FEB-11') from dual; -- 12**
select months_between('28-FEB-12', '27-FEB-11') from dual; -- 12.0322
select months_between('27-FEB-12', '28-FEB-11') from dual; -- 11.9677
is this an Oracle bug??..
-Vishwa
From the Oracle documentation:
MONTHS_BETWEEN returns number of months between dates date1 and date2. If date1 is later than date2, then the result is positive. If date1 is earlier than date2, then the result is negative. If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer. Otherwise Oracle Database calculates the fractional portion of the result based on a 31-day month and considers the difference in time components date1 and date2.
So it's following the documented behavior. It's just not what you expected.
It's not a bug because ORACLE says so, it's a logical error driven by a human (and documenting as something rigth) which is worse.
How come if difference between the last days of January and February months is exactly 1 month (29 exact days). Please see below:
MONTHS_BETWEEN('29-FEB-12','31-JAN-12')
1
With an extra day (30 days) the difference in months is less than 1. Please see below:
MONTHS_BETWEEN('29-FEB-12','30-JAN-12')
.967741935
WRONG. That's not rigth at all!
SQL Server in another hand handle this correctly:
select DATEDIFF(MM,'29-FEB-12','30-JAN-12')
select DATEDIFF(MM,'29-FEB-12','31-JAN-12')
both are 1

What kind of time stamp am I dealing with in this SQLite file?

A LONG time ago, another user wrote that he was working on a library to read data from The Hit List directly
https://groups.google.com/d/msg/the-hit-list-users/arCPzjHaZeg/J6eatDiJWB4J
It doesn't look like he ever released anything.
I was looking into reading THL's library directly, to use with a geektool script, to avoid the overhead of applescript always having to lauch THL to read data in.
I've gotten part of the way, in finding tasks that are not complete yet
SELECT * FROM ZTASK where ZCOMPLETEDDATE is NULL ;
but I'm getting confused when I try to limit it to only tasks that are DUE now. If I look at the tasks schema I see ZDUEDATE is a timestamp
sqlite> .schema ztask
CREATE TABLE ZTASK ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZARCHIVED INTEGER, ZPRIORITY INTEGER, ZNOTES INTEGER, ZPARENTLIST INTEGER, ZPARENTTASK INTEGER, ZRECURRENCE INTEGER, ZACTUALTIME FLOAT, ZCOMPLETEDDATE TIMESTAMP, ZCREATEDDATE TIMESTAMP, ZDISPLAYORDER FLOAT, ZDUEDATE TIMESTAMP, ZESTIMATEDTIME FLOAT, ZMODIFIEDDATE TIMESTAMP, ZSTARTDATE TIMESTAMP, ZCALENDARSTOREUID VARCHAR, ZNOTESUID VARCHAR, ZSTATUS VARCHAR, ZTITLE VARCHAR, ZUID VARCHAR, ZLOCALINFODICTIONARY BLOB );
Though when I try to query things, I can't seem to figure out what kind of timestamp it is. It does not seem to be unixtime or juliantime.
For example
sqlite> SELECT * FROM ZTASK where ZCOMPLETEDDATE is NULL ;
...
ZDUEDATE = 363422378
...
which shows as a due date of 2012-07-07 from The Hit List's UI but doesn't seem to match
Unix time: 1341619200
Julian time: 2456115.5
Any other suggestions ?
It's the number of seconds since January 1st 2001 GMT. I didn't choose this value myself, it's the way that Core Data and Cocoa saves dates.
For example, the value of 363422378 in your question becomes roughly 11.5 years:
363422378 seconds / 60 / 60 / 24 / 365 = 11.524048009
That looks like the number of seconds since the OS X absolute reference date:
The interval between the receiver and the system’s absolute reference date (the first instant of 1 January 2001, GMT). If the receiver is earlier than the reference date, the value is negative.
A constant is provided, NSTimeIntervalSince1970, which is [t]he number of seconds from 1 January 1970 to the reference date, 1 January 2001. It has a value of 978307200.0.

In Oracle, why does this return March 1st?

In Oracle, this returns 03/01/2010. That does not make sense to me. Anybody know why?
SELECT TO_DATE( '2010' ,'yyyy' ) AS STRANGE_YEAR_RESULT
FROM DUAL
I've tried on Oracle 10g and 11g.
Oracle needs a complete DateTime in its Date type value field, thus making it take the first day of the current month, I would guess, since you required no other information than the year. Remember that you always need to cast through TO_DATE() and TO_CHAR() dates in Oracle. Assuming so, Oracle "knows" that you will get the information required.
I don't think there is any sensible reason, it's just "what it does". It also got discussed on the OTN forums about a year ago.
Don't know, but my guess is that months are zero based, so Jan = 0, Mar = 2, etc.
"10" might be a Y2K problem in the making, but it's being interpreted as 2010.
And if no day of month is given, perhaps it's assuming the first day of the month.
Why test this? You'd never want to code this way.

Resources