Page 1 of 1

PB : Needed MACRO's for different format functions

Posted: Wed Jul 30, 2003 10:49 am
by idStefke
Dear PureBASIC programmers,

1. Can someone help me for written the next macro's in assembly or PB for:
- format floating numbers
- format percents
- format date and time

I have no experience of the WinAPI, I'm sorry

a) MACRO FormatNumber()
b) MACRO FormatPercent()

c)MACRO FormatDate()
- FormatDate have the next format options
--> d = the day of the month (1-31)
--> dd = the day of the month (01-31)
--> ddd = the first second chars of the naam of the day (su-sa)
--> dddd = the full name of the day (sunday-saterday)

--> w = the number of the day in the week (1-7)
--> ww = the number of the week in the year (1-54)

--> m = the month of the year (1-12)
--> mm = the month of the year (01-12)
--> mmm = the first three chars of the name from the month (jan-dec)
--> mmmm = the full name of the month (januari-december)

--> q = the number of the quartal in the year (1-4)

--> y = the daynumber of the year (1-366)
--> yy = the least two digits of the year (01-99)
--> yyyy = the full year (0100-9999)

MACRO FormatTime()

--> the same for the time : (:, h, hh, n, nn, s, ss, AM/PM)

I have needed this MACRO's needed for my project !

Please help me for written this MACRO (Functions)

Thanks in advance
Stephane

Why MACROS?

Posted: Thu Aug 07, 2003 5:13 am
by oldefoxx
May I ask why you require these processes be written as MACROS? Why not as procedures? Writing MACROS (in my estimation) is harder than developing the same capability in a procedure, and procedures become an embedded part of your program with the capability of making the code smaller, while MACROS involve either a preprocessor or a form of a directive structure in the compiler, and often has a more restrictive or less flexable syntax, and if used repeatedly, will make the resulting program larger. The net gain might be a small increase in speed, but the tradeoffs are not that much of an imporvement - larger program take longer to load, require more memory, and the timing in a multi-tasked computer is too complex to say that you will actually see or be able to meaure that difference in real time.

With procedures, you always have the option later of separating them out into your own separate library for other projects, or creating a DLL that
can be distributed or used independent of our original project.

Re: Why MACROS?

Posted: Thu Aug 07, 2003 7:41 am
by idStefke
Dear Guy

Can you please written this procedures of functions for me?

Thanks
Stephane

Re: PB : Needed MACRO's for different format functions

Posted: Thu Aug 07, 2003 12:08 pm
by PB
> a) MACRO FormatNumber()
> b) MACRO FormatPercent()

The above two should have examples in these forums already. Try a
search -- I know a FormatNumber() example exists somewhere here.

> c)MACRO FormatDate()

Read the docs and use the FormatDate() command:

http://www.purebasic.com/documentation/ ... tdate.html

:wink:

Date Routines

Posted: Thu Aug 07, 2003 11:16 pm
by D'Oldefoxx
Any calculations involving dates represents a challenge. This is because the llargest interval that we generally recognize that remains fairly consistent over the course of time is the year. But years vary between 365 days in length, and the occasional 366 days, when you have to add a leap day, making it a leap year. Within the year, it is the second, minute, hour, day, and week. Not that months are irregular in intervals, and one month, February, varies by whether the year is considered a leap year or not, as it gets the leap day added to the end of it when it occurs.

But weeks are irregular as well, since there is no exact multiple of seven found within a year. So a year does not always start on a Sunday and end on a Saturday. That means that in doing date calculations, you really have to do down to the most regular interval, which is the day. This results in the concept of a DayCount.

The western calendar is suppose to be based on the interval since the death of Jesus Christ, the most important single event in western theology, which is what the letters A.D. or AD, meaning After Death, represent. The counterpart to AD is B.C. or BC. meaning Before Christ. An interesting question is whether is means before the birth of Chirst, or before his death. Since Jesus is presumed to be at or anound the age of 33 to 35 when he died, before birth would leave a considerable gap in the history record, so here it is presumed to mean before death. That is, the day that Christ dies was dated January 1, year 1, and the day before is then December 31, year -1. There is no year zero, nor month zero, nor day zero. So a zero for any of these measurments signals an invalid date.

Because of the irregularities in the earth's orbit around the sun. it is necessary to average our measurements over time. The observed length of the day varies from one region on earth to another, and from one season to another. But the average over a year is 24 hours. However, the length of the year itself is closer to 365 and 1/4th days. Over four uears, the 1/4th days add up to an additional day, or leap day. But since the 1/4th day is slightly shorter than 8 hours, over a number of years the added day every four years turns out to be excessive. This happens about every 100 years, so when a leap year falls on a year that is evenly divisable by 100, we do not count that as a leap year. However, again this was an over-correction, so if the year happens to be evenly divisable by 400, then the leap day is added anyway.

As a result of these considerations, the years 1500, 1700, 1800, 1900 were not considered to be leap years. But the century marks of 1200, 1600, and 2000 were considerfed leap years. This method of computing which years are considered leap years and which were not is actually good out to about 20,000 years, which is long enough to make most people happy. There isn't enough known about permutations in the earth's orbit over extended periods of time to be sure of the outcome of future events, but what we can obsserve today tells us that the earth's rotation is being slowed by the moon, and the moon is receeding from the earth, and among other changes likely to occur, the future may have to reconsider some of its basic assumptions about how we should measure time.

So, to get a basic day count, you end up trying to resolve 365 days for every year counted, another day added for every 4th year, a day subtracted every 100 years, and a day added every 400 years. This works out to 365.2425 times the number of years. This works out fairly close to the observed solar period of about 365.2422 days accoring to some estimates. But the period is invluenced by the position on the earth were it is made from, the part of the year in which the observations is made, and the averaging to the observations over a period of years. So another source may say 365.24122 days, and another may report the period of 365.2421988 days based on observations made from near the equator. Most sources merely say 365.25 if they only consider the four year cycle, others may say 365,24 if they only observe the 100-year cycles, and those that reckon on the 400-year cycles would use the 365,2425 value.

So what makes one approach right and another wrong? In the near term, probably not much - unless your calculations straddle one of the affected date boundaries where a leap day should or should not be added. Say, like calculating periods that overlap the year 2000. For this interval you could get by with either the 4-year or 400-year approach. But if your calculations also preceed the year 1900 or extend beyond 2100, then the 400-cycle process is required.

So how mcy difference is there between 365.2425 and the slightly more accurate figure of 365.2422? Well, when we began with 365 days, and had to go to 365.25 as a closer value, the .25 worked out to be 1.4th day. But when 365.25 proved to be too much, and we went to 365.24 days, that turned out to be 1/4th - 1/100th so we added 1 every four years, and subtracted one every hundred years. But when that turned out to be too little, we went to 365.2425, which is 1/4th - 1/100/th + 25/1000th, where the last figure equates to 1/400th, so we add one every 400 years. So when we consider that we want to use 365.2422 instead, but you are already using 1/4 - 1/100 + 1/400, we have consider subtracting 3/1000, or 1 every 333 years, and adding one every 3,000 years. If we decide instead to try the 365.2421988 figure, you have 1/4th - 1/100th + 1/400th - 19/10000, or subtracting one approximately every 500 years and adding one every 10,000 years.

Well. we technically have already gone though four 500 year periods, and we have not subtracted any days for that, and we are only about 1/5th the ways towards the 10,000 year mark, so it is not really key to our current calendar. We only count the last 1800 years or so being historically accurate, except for some major events, but not necessarily by the same calendar (the gregorian calendar, which we use, was adopted rather late, and some fields still prefer the earlier julian calendar, invented by the ancient romans after christianity became a state religion, and other parts of the world may still use something else entirely). So the arguement seems to be to leave off worrying about any 500- or 10,000 year adjustment until the scientists or politics make the decision for us.

One you work out how many days tgo allow for the elapsed years, you then have to resolve the issue of how many days have lapsed in the current year, That means counting the days per month that have passed prior to the given date. If in the month of January, o days have lapesd prior to this month. If in February, 31 day (the days of January), have lapsed thus far. If March, then either 59 or 69 days have lapsed (depending upon whether this is a leap year or not as to whether February counts as 28 or 29 days. You can use any number of techiques to decide how to calculate this - some people jubble the year start so that January and Gebruary appear to end the preceeding year, and leap year gets tagged on at the end of that year, and the current year appears to start with March 1. It sounds awkward, but they make it work, Others convert the month to a number (1 -12), then use that to count through and add the individual days preceeding in each month: 0,31,28,31,30,31,30,31,31,30,31,30. Others just use a pointer lookup for the lapese days: 0,31,59,90,120,151,181,212,243,273,304,334. Then if the month turns out to be above Februaru (month 2), you add one if it is considered a leap year.

So how do you know if you made a good calendar to daycount converter? The answer to that question is that you have to compart it to the real world. After you get a day count, you can divide that count by 7 to break it down into weeks. The remainder (or Mod) of the daycount when divided by 9 indicates the day of the week, By adoption, the first day of the week is represented by 0, and the last day, Saturday, is represented by six. You can use any calendar date for any year, and verity that it falls on the correct day of the week. If it does, then it passes that test. The most critical dates to check are: Jan 1, Feb 29, Mar 1, and Dec 31. If these all fall on the respective days of the week for every year back to the start of your calendar, to the end of you calendar, then it is correct.

But what if you do not have any calendars that or forward that far? Then you can just check the critical dates of Dec 31 and Jan 1 for subsequent years and make sure that Jan 1 is dec 31's daycount + 1. You have to also verify that Feb 28 and Mar 1 are one day apart for non-leap years, and two days apart for leap years.

You still need to check that entered dates are in their correct ranges. For instance, you should not be able to enter Jan 0, or Feb 29 if it is not a leap year, or more than 31 days for any mont, or more than 30 days for the months of Apr, Jun, Sep, or Nov. You will also find it a bit of a challenge to try to write your routines to go into negative years. Hint: For negative years, consider adding the leap year before the month of march rather than after February. There are other methods, but this just means a rethink of the basic problem of going backwards in time.

How about converting a daycount back into a mm/dd/yyyy representation? Actually, this is a bit harder, but again, it involves how many days are taken up by the years and removing them, then determining if it is a leap year, and if so and the remaining daycount is more than 59, subtracting one, then subtracting the number of days for each month until you get to less than the days in the next month. Hint: Do the subtract, and if negative, subtract one month count and add back the last number of days subtracted.

How about reporting the difference between two dates? Well, you just subtract one daycount from another, then convert that into years, months, and days. But months are not all the same size, so the customary way to average out the length of 12 calendar months, which would be roughly 30.45 days each. However, some people prefer to project date differences in terms of the number of weeks, since you can easily count up or down calendar pages.

How about projecting out 30 days ahead, and getting a date. Is that possible? Of course. Just convert today's date to a daycount, add 30, and convert it back to a date. Note some people want to exclude weekends and holidays, so it can help to have a record of holidays and increment the count by 2 for every seven (add two more days each week),

Can I determine what week a date falls on in a given year? Certainly. First, determine if you are starting out on a Sunday. If so, you are in the first week already. If not, the first week will be a short one, and you have to subtract the days until the next Sunday to get to week 2. Then it is just a matter of dividing the remaining days to find out how many more weeks are in the days of the year, and add that to the 0 or 1 allowed for a partial first week,

Now here is something very important to note: You cannot solve the calendar problem using Floating Point Arithmetic. All slutions have to be
worked using integer division, which means working with Longs.

You can deal with fractions in a number of ways, such as multiplying them first by a number of years. If you multiply 365.2425 by 400, you get 146097, so if you divide a year by 400, you just multiply the result by 146097, and that takes care of the number of days that have lapsed for every 400 years. You can then do a daycount MOD 400, and find the number of days in the last 400 that you still have to convert. You can then do 365.25 times 4 and get 1461, and take that and divide it into the remaining days, and you get then number of years divisible by 4. You add 1461 for each of them, and now you have included the leap year every 4th year. You divide that number by 25 and subtract that from the daycount, and you elimiated the 1/100th that are not leap years. You already took care of the 400 year increment, so that is it, You have to total days as counted by years. Then it is just the task of figuring out the additions for the month and lapsed days, plus the days of the indicated month.

The reason that you cannot use Float arithmentic is two fold: First, floats are less accurate when really large values are involved. But that is a minor reason in this instance. The real problem is with the Floating Point Unit in modern computers. Years ago, it was understood that when you round off a value such as .5, it would round up to the next integer. If less than .5, such as .9999999, it would round down to the next lower integer value, or zero in this case. But somewhere along the way, someone argued that .5000000 should go either way. I guess that if you look at a ruler and the half inch mark between two digits, such as 6 and 6, then you would argure that 5.5 is exactly half way between the five and six, so to be fair, sometimes it should round to a five, and an equal number of times it should round to a six. The decision was that 5.5 would always count as six, and 6,6 would always count as six. In other words, by looking at whether the integer part was already an odd ir even number, you would either round up or round down.

That doesn't make a lot of sence, does it? At least it shouldnt. Because the range of 5.00000000 to 5.49999999 is exactly the same range as from 5.50000000 to 5.99999999. In other words, 5.5 is clearly closer to 6 than it is to 5, although by a small margine.

But someone, probably a bunch of bankers, prevailed on an international standards body to adopt the even-one-way, odd-the-other rule, and so the FPU in your computer will give a less-than-accurate result in some computations. And you can find engineers, programmers, and others still arguing that this is the right way, regardless.

What this means though, is that if you use floating point computations, you are going to get spotty results -- situations where you will be a day off from what you should have. As a result, you will find routines out there were the programmer qualifies his results as being within a day or two of the right answer. Bu sticking to integer arithmetic, you can get an exact result over the range of your computations.

Now, having gone to all this detail, why have I failed to respond to the request for my own routines? It comes down to two things: I believe that learning to program is more about doing than it is about getting. If someone wants to write code and post it for others, fine. I enjoy the chance to enrich my own library that was as much as the next. But it is still left to me to figure out what to do with it. When someone askse others to write code for them, that is an imposition, and it goes against the grain of learning to do it for yourself, So I am willing to tell you enough to let you try it on your own, and some approaches that might make it easier to do, but I won't write the code directly for you.

Now as it happens, I (and others) have tackled the challenge of date, day, week, and similar routines in the past. Many of those works are available on various forums, in code archives, and in libraries. So if you want to look for them, they are out there. But you still have to figure out how to use them, so what is the net gain? You certainly miss the opportunity to step up to the plate and hit that pitch for yourself. It isn't enough to always choose to try to get a walk instead.

Posted: Fri Aug 08, 2003 1:08 am
by Karbon
The western calendar is suppose to be based on the interval since the death of Jesus Christ, the most important single event in western theology, which is what the letters A.D. or AD, meaning After Death, represent. The counterpart to AD is B.C. or BC. meaning Before Christ.
Actually A.D is Anno Domini - latin for Year of Lord... Common mistake to think it's After Death..

B.C. has two different definitions, one to Christians and one to everyone else. Before Common erra is the generally accepted non-Christian definition as I understand it.

Re: Date Routines

Posted: Fri Aug 08, 2003 9:08 am
by idStefke
Dear Sir

Thanks for your explean of problem definitions.
Can you write this for me in code?

Kind regards
Stephane

I would like two build this functions into an DLL file for using other languages such as PowerBASIC.

Re: Date Routines

Posted: Fri Aug 08, 2003 9:41 am
by Rings
idStefke wrote:Can you write this for me in code?
no problem.transfer 250,- Euro to my bank-account here at:

Bank of Germany,10020050, Nr. 1112xxxxxxx.

Code follows after payment :lol:

Posted: Fri Aug 08, 2003 9:44 am
by LarsG
I'll do it for 239 Euro.. :twisted:

-Lars

Re: Date Routines

Posted: Fri Aug 08, 2003 9:51 am
by PB
> I would like two build this functions into an DLL file for using other
> languages such as PowerBASIC.

I don't think this is permitted in PureBasic's license... Fred?

Posted: Fri Aug 08, 2003 9:59 am
by Fred
He can if it redone it fully and don't use the FormatDate() functions. But I don't see the point of his post, he doesn't even try to code but ask for other to code even after all the needed informations by D'Oldefoxx. It's a Beginner section, not a 'I want someone to write some code' section.

Posted: Fri Aug 08, 2003 10:06 am
by Rings
www.rentacoder.com can be the solution