May 06, 2024, 06:33:55 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Date: sum and subtract days to a date

Started by JoaoAfonso, June 20, 2008, 04:54:51 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

JoaoAfonso

Good morning.

I am writing today to ask how you (who needed already this function) figure out the correct date when you sum X days to a date.
I work around julian days (and checked the projects about it), but eventually due to some calendar shapes or a bad function, there are "bugs" in the returning date (from julian to our calendar), like it return days such as 30FEV or 32APR (there is no error in the long term, because if I sum one day more to 32APR it returns 03JUN... for comparisons this is acceptable, but if I care about the exact day, is not).

Also tested things around date. If I have 2 different dates, I can compare them with success (if date$ 1>date$ 2 then...), but if I want to do a thing like
- date$=20JAN08
- date$=date$+20, which I wanted to return 09FEV08.

I want to do a weekly calendar with tasks to do. I do the following:
- I have a SysMonthCal32
- Below SysMonthCal32, there is a table of 7 columns, one column per day
- Clicking in any date in calendar, it opens that week calendar, from monday to sunday, and shows tasks in table for that week (clicking in monday, tuesday, etc, of that week, the results are always from the same week)
- I work with julians, so every task is put in the table in the correct days
- What I cannot do correctly is write the correct day in the top of each column (the first week of JUN08 returns 26MAY08, 27MAY08, 28MAY08, 29MAY08, 30MAY08, 31MAY08, 32MAY08, where this 32MAY08 should be 01JUN08)

Thaks in advance for any tip or workaround you can give.
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

JoaoAfonso

Tried also this:

DECLARE IMPORT,GetDateFormatA(INT locale, INT flags, POINTER date, STRING format, STRING out, INT outlen)

where OUT will be the return date$ from a systemtime variable (the pointer variable in this function).

with POINTER date as systemtime,

TYPE SYSTEMTIME,2
DEF wYear:WORD
DEF wMonth:WORD
    DEF wDayOfWeek:WORD
    DEF wDay:WORD
    DEF wHour:WORD
    DEF wMinute:WORD
    DEF wSecond:WORD
    DEF wMilliseconds:WORD
ENDTYPE


I tried to add or subtract date.wDay the number of days of that week and get the new format. Works ok for every date unless it is end of month, where date.wDay can receive negative numbers or positive higher than the last day of month (thought dateformat could fix this automatically).
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

LarryMc

Joao

Attached is some code from the old IBasic Forums that might help you solve your problem.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

The OS has functions to help you.

A FILETIME structure is really an UINT64

SystemTimeToFileTime and FileTimeToSystemTime converts back and forth.   The UINT64 returned represents 100ns intervals. 

So you can get the current time in a SystemTime UDT, convert it to a FILETIME, and add or subtract absolute values from it, remember to use the 'q' modifier in your constants since your dealing with a 64 bit value. 

1 second = 1000ms = 10000000q 100ns intervals

You can also get the 'current' time in a filetime value, which is returned in UTC time, convert it to local time and add and subtract from there.  Which is what I normally do when I want to make something happen relative to now.

Quote
UINT64 utc,local
SYSTEMTIME st
'utc time
GetSystemTimeAsFileTime(utc)
'local time
FileTimeToLocalFileTime(utc,local)

'add a day

local += 1440q * 60q * 10000000q

'convert back

FileTimeToSystemTime(local, st)

Paul.

Ionic Wind Support Team

JoaoAfonso

Guess there are at least 2 different ways of calculate julian calendar. Read somethings not too deep about it, but I was assuming other formulas for calculating julian days. The starting day for each formulas might be different (has to be with history), but the relation between days is the same (if I want to check the number of days between 01JAN08 and 10JAN08, be 01JAN08 a julian day number 10 or 100, the difference will always be 10), so when I use just julians, all goes well. The bug in my program is in the function that transform julian days (fake ones?) in ISO date.

I will now make a conversion from my julian dates to the true julian dates using this code you attached. Thank you very much, it is of great use.

Btw, eventually for curiosity, or something, I will post the routines I was using (and if I am not wrong were got also from old foruns) and the new ones from the file Larry sent.

The ones with error
SUB julian(dataa:STRING),INT
INT useday,usemonth,useyear,ly,yearspassed,daysinfullyears,leapyearspassed,julianc,yeartodate,retval
useDay=VAL(LEFT$(dataa,2)):useMonth=VAL(MID$(dataa,3,2)):useYear=VAL(RIGHT$(dataa,4)):
ly = isLeapYear(useYear)
YearsPassed = useYear - 1901
DaysInFullYears = YearsPassed * 365
LeapYearsPassed = INT(YearsPassed/4)
julianc = DaysInFullYears + LeapYearsPassed - 1
yearToDate=0
SELECT useMonth
CASE 1
yearToDate = 0
CASE 2
yearToDate = 31
CASE 3
yearToDate = 59 + ly
CASE 4
yearToDate = 90 + ly
CASE 5
yearToDate = 120 + ly
CASE 6
yearToDate = 151 + ly
CASE 7
yearToDate = 181 + ly
CASE 8
yearToDate = 212 + ly
CASE 9
yearToDate = 243 + ly
CASE 10
yearToDate = 273 + ly
CASE 11
yearToDate = 304 + ly
CASE 12
yearToDate = 334 + ly
ENDSELECT
retval=julianc+yearToDate+useDay
RETURN retval-2
ENDSUB


SUB julianinv(dataa:INT),STRING
INT theyear,themonth,theday,ayears,year,ly,i
STRING resultado,diaj,mesj,anoj
TheYear = 0 : TheMonth = 0 : TheDay = 0
aYears = INT(dataa/365.25)+1
year = 1901:dataa = dataa + 1:ly = 0
FOR i = 1 TO aYears
IF dataa<=(365+ly)
TheYear=year
GOTO endfor
ENDIF
dataa =dataa - (365+ly)
year = year + 1
ly = isLeapYear(year)
LABEL endfor
NEXT i
IF dataa <= 31
TheMonth = 1:TheDay = dataa
ENDIF
IF dataa > 31  & dataa <= 59 + ly
TheMonth = 2:TheDay = dataa - 31 + ly
ENDIF
IF dataa > 59 + ly & dataa <= 90 + ly
TheMonth = 3:TheDay = dataa - 59 + ly
ENDIF
IF dataa > 90 + ly & dataa <= 120 + ly
TheMonth = 4:TheDay = dataa - 90 + ly
ENDIF
IF dataa > (120 + ly) & dataa <= (151 + ly)
TheMonth = 5:TheDay = dataa - 120 + ly
ENDIF
IF dataa > 151 + ly & dataa <= 181 + ly
TheMonth = 6:TheDay = dataa - 151 + ly
ENDIF
IF dataa > 181 + ly & dataa <= 212 + ly
TheMonth = 7:TheDay = dataa - 181 + ly
ENDIF
IF dataa > 212 + ly & dataa <= 243 + ly
TheMonth = 8:TheDay = dataa - 212 + ly
ENDIF
IF dataa > 243 + ly & dataa <= 273 + ly
TheMonth = 9:TheDay = dataa - 243 + ly
ENDIF
IF dataa > 273 + ly & dataa <= 304 + ly
TheMonth = 10:TheDay = dataa - 273+ly
ENDIF
IF dataa > 304 + ly & dataa <= 334 + ly
TheMonth = 11:TheDay = dataa - 304 + ly
ENDIF
IF dataa > 334 + ly & dataa <= 365 + ly
TheMonth = 12:TheDay = dataa - 334 + ly
ENDIF
diaj=LTRIM$(STR$(theDay))
IF LEN(diaj)=1 THEN diaj="0"+diaj
mesj=mes_numero_abreviado(theMonth)
anoj=RIGHT$(STR$(theYear),2)
resultado=diaj+mesj+anoj
RETURN resultado
ENDSUB


And the "new" ones, with true julian dates:
Sub Julian(year :int, month :int, day : int),int
def a, jd, m, y : int
a = (14 - month)/12
y = year + 4800 - a
m = month + 12 * a - 3
jd = day + (153 * m + 2)/5 + y * 365 + y/4 - y/100 + y/400 - 32045
return jd
endsub


sub date_ISO(jd : int),string
def ret : string
def a,b,c,d,e,m,day,month,year,x : int
a = JD + 32044
b = (4 * a + 3)/146097
c = a - (b * 146097)/4
d = (4 * c + 3)/1461
e = c - (1461 * d)/4
m = (5 * e + 2)/153
day   = e - (153 * m + 2)/5 + 1
month = m + 3 - 12*(m/10)
year  = b * 100 + d - 4800 + m/10
ret = ltrim$(rtrim$(str$(year))) + "/"
ret = ret + right$("0"+ltrim$(rtrim$(str$(month))),2)
ret = ret + "/" + right$("0"+ltrim$(rtrim$(str$(day))),2)
' above 3 lines can be a single line but this is more readable.
' upslash "/" is used as a separator for date's elements
return ret
endsub


Thank you again.
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900

JoaoAfonso

Paul, thanks for your answer too. Always easier and simple :) Anyway, as I am used to the mechanics of julian days and comparisons, I guess I will just fix the routines and make the necessary conversions. Seems easier at this time.
JoÃÆ'ƒÂÃ,£o Afonso
Viriato
-----------------
Iberia MUD
www.iberiamud.com
iberiamud.com:5900