How to execute “between” in the Arabic (hijri) calendar and save it as a “date” in MySQL?

My question is actually my ultimate goal. So far I have 2 questions.

  • How to save arabic date as "date" in mysql? because I converted the Gregorian language to Hijri, and then using preg_replace (php, currently final in Java) will change the numbers to Arabic ascii hex ... and then save it in MySQL as varchar.

I know about the cp1256_general_ci collation, which allows us to store in Arabic, but for now, for simplicity, I have set it aside. utf-8_general does a great job. Therefore, saving as varchar is not a problem, saving as a "date".

  • Fulfillment of requests on it. I thought that the requirements would end, but now the task is to execute queries such as date 'between' xyz and pqr ... Also, the restriction is to "keep it only in Arabic."

Any inputs are greatly appreciated.

+4
source share
2 answers

SQL Dates

I would think of it this way: in fact, the server stores the date as a link for that day. It does not concern you. When storing data or reading data from such a date column, the server presents this date using a specific calendar, which is agreed upon. What I'm trying to say, I would not consider the stored value of a gregorian, although it may well be. I would prefer that the rescheduled date be gregorian.

Thus, the best solution, in my opinion, is to accept this fact and the transformation between Gregorians and Hijras on the application side. That way you can use regular checks between .

Numeric Lines

If this is not possible, because the language-dependent conversion is too complicated or because the mapping between Hijri and Grogorian is not unique or unknown in advance, then you will need to save the date in some other form. Possible forms that come to my mind are either varchar containing the lines of the form YYYY-MM-DD , with letters denoting numbers. This scheme ensures that the strings will be compared with the dates that they represent, so you can use between for them. However, including these lines in your dates will still be difficult.

One or more numeric columns

So, I would suggest that you use three columns, each of which contains a date number. Then you could use 10000*year + 100*month + day_of_month to get one number for each day, which you could use for comparison, and between . On the other hand, you can use the ELT function in your queries to return the number for the month back to the name. If performance is a problem, you might be better off saving only one number and splitting it into parts after selection. In the Gregorian calendar, it will look like this:

 CREATE TABLE tableName (myDate DECIMAL(8)); SELECT myDate DIV 10000 AS year, ELT((myDate DIV 100) MOD 100, "Jan", "Feb", …) AS month, myDate MOD 100 AS day_of_month FROM tableName WHERE myDate BETWEN 20121021 AND 20121023; 

Compatibility and Convenience

If you need to maintain read-only compatibility with code that expects a single text date column, you can use VIEW to provide this. For example, for the German Gregorian format DD. MMMM YYYY DD. MMMM YYYY you can use this code:

 CREATE VIEW compatibleName AS SELECT CONCAT(myDate MOD 100, ". ", ELT((myDate DIV 100) MOD 100, "Januar", "Februar", …), ". ", myDate DIV 10000) as dateString, * -- or explicitely name other columns needed for compatibility FROM tableName 

Decoding Strings

If you need read and write access by another application in line format, you will have to parse these lines yourself. You can do it at the SQL level. Useful tools are SUBSTRING_INDEX to split the string into fields and FIELD to turn the month name into a number. You might want to add a trigger to the database, which ensures that your lines will always be in a valid format that you can decompose in this way. This question provides details on how to use triggers to enforce such checks.

+3
source

You can save as a date directly. I am a normal day. my mysql functions

 DELIMITER $$ DROP FUNCTION IF EXISTS `kdmtest`.`IntPart` $$ CREATE FUNCTION `kdmtest`.`IntPart` (FloatNum float) RETURNS INT BEGIN if (floatNum< -0.0000001) then return ceil(floatNum-0.0000001); else return floor(floatNum+0.0000001); end if; END $$ DELIMITER ; DELIMITER $$ DROP FUNCTION IF EXISTS `kdmtest`.`Hicri` $$ CREATE DEFINER=`root`@`localhost` FUNCTION `Hicri`(MiladiTarih date) RETURNS date BEGIN declare d,m,y,jd,l,n,j int; set d=day(MiladiTarih); set m=month(MiladiTarih); set y=year(MiladiTarih); if ((y>1582) or((y=1582) and (m>10)) or ((y=1582) and (m=10) and (d>14))) then set jd=intpart((1461*(y+4800+intpart((m-14)/12)))/4)+intpart((367*(m-2-12*(intpart((m-14)/12))))/12)- intpart( (3* (intpart( (y+4900+ intpart( (m-14)/12) )/100) ) ) /4)+d-32075; else set jd = 367*y-intpart((7*(y+5001+intpart((m-9)/7)))/4)+intpart((275*m)/9)+d+1729777; end if; set l=jd-1948440+10632; set n=intpart((l-1)/10631); set l=l-10631*n+354; set j=(intpart((10985-l)/5316))*(intpart((50*l)/17719))+(intpart(l/5670))*(intpart((43*l)/15238)); set l=l-(intpart((30-j)/15))*(intpart((17719*j)/50))-(intpart(j/16))*(intpart((15238*j)/43))+29; set m=intpart((24*l)/709); set d=l-intpart((709*m)/24); set y=30*n+j-30; return concat(y,'-',m,'-',d); END $$ DELIMITER ; DELIMITER $$ DROP FUNCTION IF EXISTS `kdmtest`.`Miladi` $$ CREATE FUNCTION `kdmtest`.`Miladi` (HicriTarih date) RETURNS date BEGIN declare d,m,y,jd,l,n,j,i,k int; set d=day(HicriTarih); set m=month(HicriTarih); set y=year(HicriTarih); set jd=intPart((11*y+3)/30)+354*y+30*m-intPart((m-1)/2)+d+1948440-385; if (jd> 2299160 ) then set l=jd+68569; set n=intPart((4*l)/146097); set l=l-intPart((146097*n+3)/4); set i=intPart((4000*(l+1))/1461001); set l=l-intPart((1461*i)/4)+31; set j=intPart((80*l)/2447); set d=l-intPart((2447*j)/80); set l=intPart(j/11); set m=j+2-12*l; set y=100*(n-49)+i+l; else set j=jd+1402; set k=intPart((j-1)/1461); set l=j-1461*k; set n=intPart((l-1)/365)-intPart(l/1461); set i=l-365*n+30; set j=intPart((80*i)/2447); set d=i-intPart((2447*j)/80); set i=intPart(j/11); set m=j+2-12*i; set y=4*k+n+i-4716; end if; return concat(y,'-',m,'-',d); END $$ DELIMITER ; 
+3
source

Source: https://habr.com/ru/post/1441188/


All Articles