Hi,

I've done some work on saying dates correctly in German; attached you can find the diff. Some tests anyone?

I've implemented it the way that it says dates like "Dienstag, neunundzwanzigster Mai Zweitausendvier" for 2004-05-29 and "zw�lf Uhr dreiundf�nfzig" for times, here "12:53".
IMO this is the correct format for german times and dates.


The format line in voicemail.conf "de=Europe/Berlin|'vm-received' q 'digits/at' H 'digits/oclock' M" will then produce "Dienstag, neunundzwanzigster Mai Zweitausendvier um zw�lf Uhr dreiundf�nfzig".

The patch also fixes a problem in say_number_full_de() where it tried to stream empty filenames.

But be warned, this patch has an impact on existing stuff: First, the parameter 'q' is changed from ABdY to AdBY when using German localization. This doesn't match the documentation then.
Second, some sound files at http://www.karl.aegee.org/asterisk.nsf/HT/sound-de, linked by voip-info.org, have to be changed, namely the h-xx.gsm files. They say for example "ersten", "zweiten", "dreizehnten" etc. but have to be "erster", "zweiter", dreizehnter".


A possibility to reuse the existing sound files would be to say an "am" before the day of month, so that it sounds like "Dienstag, am neunundzwanzigsten Mai...". I'm still thinking about a flexible solution to switch between these two formats.


Maybe it is helpful though.

Regards,
Andy
Index: say.c
===================================================================
RCS file: /usr/cvsroot/asterisk/say.c,v
retrieving revision 1.34
diff -u -r1.34 say.c
--- say.c	23 Jun 2004 20:19:12 -0000	1.34
+++ say.c	29 Jun 2004 09:59:42 -0000
@@ -704,6 +704,7 @@
 	int playh = 0;
 	int t = 0;
 	int mf = 1;                            /* +1 = Male, Neutrum; -1 = Female */
+	int fna_set = 0;
 	char fn[256] = "";
 	char fna[256] = "";
 	if (!num) 
@@ -761,6 +762,7 @@
 			if (thousands == 1) {
 				snprintf(fn, sizeof(fn), "digits/1N");
 				snprintf(fna, sizeof(fna), "digits/thousand");
+				fna_set = 1;
 			} else {
 				res = ast_say_number_full_de(chan, thousands, ints, language, options, audiofd, ctrlfd);
 				if (res)
@@ -774,6 +776,7 @@
 			if (millions == 1) {
 				snprintf(fn, sizeof(fn), "digits/1N");
 				snprintf(fna, sizeof(fna), "digits/million");
+				fna_set = 1;
 			} else {
 				res = ast_say_number_full_de(chan, millions, ints, language, options, audiofd, ctrlfd);
 				if (res)
@@ -793,7 +796,8 @@
 					res = ast_waitstream(chan, ints);
 			}
 			ast_stopstream(chan);
-			if(!ast_streamfile(chan, fna, language)) {
+			/* without fna_set check it tried to stream an empty filename */
+			if(fna_set && !ast_streamfile(chan, fna, language)) {
 				if (audiofd && ctrlfd) 
 					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
 				else  
@@ -801,6 +805,7 @@
 			}
 			ast_stopstream(chan);
 			strcpy(fna, "");
+			fna_set = 0;
 		}
 	}
 	return res;
@@ -2098,7 +2103,6 @@
 }
 
 /* German syntax */
-/* NB This currently is a 100% clone of the English syntax, just getting ready to make changes... */
 int ast_say_date_with_format_de(struct ast_channel *chan, time_t time, char *ints, char *lang, char *format, char *timezone)
 {
 	struct tm tm;
@@ -2134,72 +2138,33 @@
 				break;
 			case 'd':
 			case 'e':
-				/* First - Thirtyfirst */
-				if ((tm.tm_mday < 21) || (tm.tm_mday == 30)) {
-					snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", tm.tm_mday);
+			{
+				int day = tm.tm_mday;
+				if(day > 20 && day != 30) {
+					int lastdig = day % 10;
+					day -= lastdig;
+					snprintf(nextmsg,sizeof(nextmsg), "digits/%d-and", lastdig);
 					res = wait_file(chan,ints,nextmsg,lang);
-				} else if (tm.tm_mday == 31) {
-					/* "Thirty" and "first" */
-					res = wait_file(chan,ints, "digits/30",lang);
-					if (!res) {
-						res = wait_file(chan,ints, "digits/h-1",lang);
-					}
-				} else {
-					/* Between 21 and 29 - two sounds */
-					res = wait_file(chan,ints, "digits/20",lang);
-					if (!res) {
-						snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - 20);
-						res = wait_file(chan,ints,nextmsg,lang);
-					}
+
 				}
-				break;
+				if(!res) {
+					snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d", day);
+					res = wait_file(chan,ints,nextmsg,lang);
+				}
+			}
+			break;
 			case 'Y':
 				/* Year */
 				if (tm.tm_year > 99) {
-					res = wait_file(chan,ints, "digits/2",lang);
-					if (!res) {
-						res = wait_file(chan,ints, "digits/thousand",lang);
-					}
-					if (tm.tm_year > 100) {
-						if (!res) {
-							/* This works until the end of 2020 */
-							snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
-							res = wait_file(chan,ints,nextmsg,lang);
-						}
-					}
+				        res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char*)NULL);
 				} else {
 					if (tm.tm_year < 1) {
 						/* I'm not going to handle 1900 and prior */
 						/* We'll just be silent on the year, instead of bombing out. */
 					} else {
 						res = wait_file(chan,ints, "digits/19",lang);
-						if (!res) {
-							if (tm.tm_year <= 9) {
-								/* 1901 - 1909 */
-								res = wait_file(chan,ints, "digits/oh",lang);
-								if (!res) {
-									snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
-									res = wait_file(chan,ints,nextmsg,lang);
-								}
-							} else if (tm.tm_year <= 20) {
-								/* 1910 - 1920 */
-								snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
-								res = wait_file(chan,ints,nextmsg,lang);
-							} else {
-								/* 1921 - 1999 */
-								int ten, one;
-								ten = tm.tm_year / 10;
-								one = tm.tm_year % 10;
-								snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
-								res = wait_file(chan,ints,nextmsg,lang);
-								if (!res) {
-									if (one != 0) {
-										snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
-										res = wait_file(chan,ints,nextmsg,lang);
-									}
-								}
-							}
-						}
+				        	if(!res)
+							res = ast_say_number(chan, tm.tm_year, ints, lang, (char*)NULL);
 					}
 				}
 				break;
@@ -2222,53 +2187,16 @@
 					if (tm.tm_hour < 10) {
 						res = wait_file(chan,ints, "digits/oh",lang);
 					}
-				} else {
-					/* e.g. eight */
-					if (tm.tm_hour == 0) {
-						res = wait_file(chan,ints, "digits/oh",lang);
-					}
 				}
 				if (!res) {
 					if (tm.tm_hour != 0) {
-						int remainder = tm.tm_hour;
-						if (tm.tm_hour > 20) {
-							res = wait_file(chan,ints, "digits/20",lang);
-							remainder -= 20;
-						}
-						if (!res) {
-							snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
-							res = wait_file(chan,ints,nextmsg,lang);
-						}
+						res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
 					}
 				}
 				break;
 			case 'M':
 				/* Minute */
-				if (tm.tm_min == 0) {
-					res = wait_file(chan,ints, "digits/oclock",lang);
-				} else if (tm.tm_min < 10) {
-					res = wait_file(chan,ints, "digits/oh",lang);
-					if (!res) {
-						snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
-						res = wait_file(chan,ints,nextmsg,lang);
-					}
-				} else if ((tm.tm_min < 21) || (tm.tm_min % 10 == 0)) {
-					snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
-					res = wait_file(chan,ints,nextmsg,lang);
-				} else {
-					int ten, one;
-					ten = (tm.tm_min / 10) * 10;
-					one = (tm.tm_min % 10);
-					snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
-					res = wait_file(chan,ints,nextmsg,lang);
-					if (!res) {
-						/* Fifty, not fifty-zero */
-						if (one != 0) {
-							snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
-							res = wait_file(chan,ints,nextmsg,lang);
-						}
-					}
-				}
+				res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
 				break;
 			case 'P':
 			case 'p':
@@ -2303,7 +2231,7 @@
 				}
 				break;
 			case 'q':
-				/* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
+				/* Shorthand for "" (today), "Yesterday", A (weekday), or AdBY (differs from english) */
 				{
 					struct timeval now;
 					struct tm tmnow;
@@ -2323,7 +2251,7 @@
 						/* Within the last week */
 						res = ast_say_date_with_format(chan, time, ints, lang, "A", timezone);
 					} else {
-						res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
+						res = ast_say_date_with_format(chan, time, ints, lang, "AdBY", timezone);
 					}
 				}
 				break;
@@ -2332,31 +2260,11 @@
 				break;
 			case 'S':
 				/* Seconds */
-				if (tm.tm_sec == 0) {
-					snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
-					res = wait_file(chan,ints,nextmsg,lang);
-				} else if (tm.tm_sec < 10) {
+				if(tm.tm_sec < 10) {
 					res = wait_file(chan,ints, "digits/oh",lang);
-					if (!res) {
-						snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
-						res = wait_file(chan,ints,nextmsg,lang);
-					}
-				} else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
-					snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
-					res = wait_file(chan,ints,nextmsg,lang);
-				} else {
-					int ten, one;
-					ten = (tm.tm_sec / 10) * 10;
-					one = (tm.tm_sec % 10);
-					snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
-					res = wait_file(chan,ints,nextmsg,lang);
-					if (!res) {
-						/* Fifty, not fifty-zero */
-						if (one != 0) {
-							snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
-							res = wait_file(chan,ints,nextmsg,lang);
-						}
-					}
+				}
+				if(!res && tm.tm_sec > 0) {
+					res = ast_say_number(chan, tm.tm_sec, ints, lang, (char*)NULL);
 				}
 				break;
 			case 'T':

Reply via email to