PDA

Tam Sürümünü Görmek İçin : C++ Tarih Bilgisi


kasif
16/04/2008, 17:01
Merhaba,

C++ 'da tarih bilgisine nasıl ulaşabilirim. Yani ekrana veya bir dosyaya 16.04.2008 veya 16.Nisan.2008 nasıl yazdırabilirim?


hgedek
17/04/2008, 04:16
time.h kütüphanesinden asctime(struct tm*) yada ctime(time_t *) yapılarını kullanarak string türünde değer ile yapabilirsin.

#include <stdio.h>
#include <time.h>

int main ()
{
time_t rawtime;
struct tm * timeinfo;

time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ( "The current date/time is: %s", asctime (timeinfo) );

return 0;
}

#include <stdio.h>
#include <time.h>

int main ()
{
time_t rawtime;

time ( &rawtime );
printf ( "The current local time is: %s", ctime (&rawtime) );

return 0;
}

kasif
17/04/2008, 14:58
Merhaba,
Bu kodların ikisinde de şöyle bir çıktı veriyor.

The current local time is: Thu Apr 17 14:55:26 2008

ama ben aşağıdaki gibi bir şey istiyorum onu nasıl yapabilirim.

The current local time is: 17.04.2008 veya
The current local time is: 17.Nisan.2008

Yani gelen zaman bilgisini kendi kullanımıma uygun olarak nasıl formatlarım?

acehreli
17/04/2008, 19:47
strftime'i kullanabilirsin. Ama o time_t degil, 'struct tm' kullanir. Benim ortamimdaki strftime'in belgesinde bir ornek vermisler:


#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
char outstr[200];
time_t t;
struct tm *tmp;

t = time(NULL);
tmp = localtime(&t);
if (tmp == NULL) {
perror("localtime");
exit(EXIT_FAILURE);
}

if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) {
fprintf(stderr, "strftime returned 0");
exit(EXIT_FAILURE);
}

printf("Result string is \"%s\"\n", outstr);
exit(EXIT_SUCCESS);
} /* main */


Ali

kasif
18/04/2008, 10:11
Merhaba,
Henüz çok yeniyim ama anladığım kadarı ile bu kodlar c kodları peki c++ içinde mi aynı kodlar kullanılır. Yoksa başka bir yolu var mıdır?

Ayrıca anladığım kadarı ile time_t tipinde bir tip var ve bu bir zaman tipi öncelikle bu tipten bir değişken tanımlıyoruz. Ancak bu değişenin şu an bir anlamı yok çünkü içinde zaman bilgisi yok bunun içinde time adındaki fonksiyonu çağırıyouz. time fonksiyonu time_t tipinde bir pointer ister, bundan dolayı time_t tipinde tanımladığımız değişkeni bu fonksiona geçiyoruz ve değişkenimiz artık zaman bilgisini içerir duruma geliyor.

Ancak hala bu değişkeni kullanamıyoruz. Bunun için bize bir yardımcı araç daha gerekli, daha doğrusu time_t tipinde tanımlanmış zaman paketini açacak bir anahtara ihtiyaç duyuyoruz. Bunun içinde struct tm tipinde bir değişken tanımlıyoruz.Bu değişken time_t tipindeki değişken paketi çözerek bizim kullanacağımız hale getiriyor ama bu esnada bir sıkıntı daha var. Paketi açma yönteminide söylememiz gerekiyor. Burada devreye localtime isimli fonksiyon giriyor ve paket açılıyor artık elimizde yerel zaman bilgisini içeren ve kullanabileceğimiz bir struct tm tipinde yapımız oluyor. Bunu ekrana yazmak istersek küçük bir yardıma daha ihtiyaç duyuyoruz. asctime fonksiyonu bu değeri ekrana yazılacak hale getiriyor. Benim C++'da zaman işleminden anladıklarım bunlar yanlışlarım varsa lütfen düzeltin.

Ancak anlamadığım kısım struct tm *timeinfo bu şekilde tanımlanınca örnegin timeinfo.tm_wday şekilde bir kullanım yapamıyorum. Oysa ben gün /ay /yil ayrı ayrı yazdırabilirim diye düşünüyorum çünkü yapının içinde bunlara ulaşabiliyorum ama struct tm timeinfo bu şekilde taımladığım zaman o zamanda başka yerde hata veriyor. Neyi kaçırıyorum?

acehreli
18/04/2008, 17:38
C++, C'nin standart kutuphanesini de icerir. Ayni kodlari belki de hic karsilasmayacagin durumlar disinda her zaman kullanabilirsin.

Yine de C++ icin ayri kutuphaneler de bulabilirsin. Ornegin:

http://boost.org/doc/libs/1_35_0/doc/html/date_time.html

Hatta bu kutuphane C++'in yeni standardina eklenmis veya yakinda eklenecek de olabilir. Bu konudan emin degilim. Ama Boost kutuphanesini standart C++'in bir uzantisi olarak gorebilirsin.

Anlattiklarinin cogu dogru. Ama iki programi ayni anda anlatmis gibi olmussun. Bir kac duzeltme yapilabilir:

1) time'in bir isaretci istedigini soyluyorsun. Bu onceki kod icin dogru, ama son programda ona isaretci vermiyoruz (NULL, gecersiz isaretci degeridir). Cunku time zaman bilgisini dOndUrUr de... Biz de bundan yararlanarak onun dOndUrdugunu t'ye esitliyoruz.

2) Zaman pakedini "acmak" yerine, bir tUrU baska bir tUre "dOnusturmek" daha dogru geliyor. asctime fonksiyonu time_t'den anlamadigi icin, time_t'yi tm'e dOnusturen localtime'i kullaniyoruz.

Yoksa zaten time_t'yi kullanan bir fonksiyon cagiracak olsak localtime'a gerek kalmazdi; cunku dOnUsum gerekmezdi.

3) Son programda bir de strftime kullaniliyor. timeinfo'nun elemanlarini teker teker sen kullanacagina strftime'a hangi formati istedigini soyleyebiliyorsun. Son program ornegi, komut satirindan aldigi formati kullaniyor ama bunu sana soylemeyi unutmus. :)

struct tm *tmp;

satirindan sonra su kod blogunu eklersen sana nasil kullanilacagini soyleyecek:


if (argc != 2) {
fprintf(stderr, "Kullanim:\n %s \"gosterim formati\"\n", argv[0]);
fprintf(stderr, "Ornek: %s \"%%e %%B %%A\"\n", argv[0]);
exit(EXIT_FAILURE);
}


Format icin neler kullanilabilecegini strftime'in belgesinden okuyabilirsin (Google'da "man strftime" diye arat.)

Son olarak, sordugun soru isaretcilerle ilgili.

struct tm *timeinfo;

yazdigin zaman elinde bir tm yok, bir tm gosteren bir isaretci var. Elinde bir tm olmadigi icin,

timeinfo.tm_wday

yazamazsin. timeinfo bir "isaretci" oldugu icin onun gosterdigi tm'in tm_wday'ini kullanabilmek icin soyle yazman gerekiyor:

timeinfo->tm_wday

Oteki durumda da

struct tm timeinfo;

yazinca elinde bir tm oluyor ama onu localtime'in dOndUrdUgu degere esitleyemiyorsun cunku localtime bir tm degil, bir tm isaretcisi dOndUrur.

Ali

uszr
18/04/2008, 18:36
#include <time.h>
static char *getfdate()
{
static char date[128];
time_t t = time(NULL);
struct tm *tp = localtime(&t);

if (!tp)
return NULL;

strftime(date, sizeof(date), "%d.%m.%Y", tp);
return date;
}

kasif
18/04/2008, 18:47
Merhaba, ayrıntılı açıklama için teşekkür ederim.

1. time_t tipinden tanımladığımız değişkenin içeriğini doldurmak için time isimli fonksiyonu kullanıyoruz. Bunun iki kullanımını gördüm
time ( &rawtime ); veya rawtime = time (NULL);

Bu kullanimlarin birbirine göre bir avantajı var mı?
2. struct tm konusundaki sorumu harika yanıtlamışsınız tam olarak anladım teşekkürler.

3. Sizin gönderdiğiniz kodları çalıştıramadım. MS Visual C++ 6.0 kullanıyorum ve aşağıdaki satırda Access vialation hatası veriyor.

if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0)

Son olarak strftime'a gerek görmüyorum bilmem yanlışmıyım ama eğer ay gün yil değerlerini elde edebiliyorsam zaten tarihle ilgili her türlü formatta çıktı oluşturabilirim strftime'la uğraşmama gerek kalmaz diye düşünüyorum. struct tm zaten bana ay gün yil bilgisini veriyor ama bu benim düşüncem tabi

acehreli
18/04/2008, 21:15
Tesekkure tesekkur ederim ama hic gerek yok; birlikte sohbet ederek ogreniyoruz. :)

1) time'in iki kullanimi esdeger ve artik gereksiz bir esneklik. Kendisine verilen isratectinin icini doldurur ve ayni degeri geri dOndUrur. Boylece hem bir degiskene atama yapip hem de o degerle baska bir fonksiyonu ayni anda cagirabiliriz:

// Hem t kuruluyor hem de o deger bir_fonksiyon'a gidiyor:
bir_fonksiyon(time(&t));

Ama benim gordugum kadariyla bu tur zincirleme cagrilar yaygin degil. Onun yerine hemen hemen herkes zaten soyle iki satirda yapar:

time(&t);
bir_fonksiyon(t);

Veya soyle iki satirda yaparlar:

t = time(NULL);
bir_fonksiyon(t);


3) O ornekte formati komut satirindan vermen gerekiyor. Benim en son verdigim ek satirlari programa eklersen argv[1] olmadigi durumlarda erisim hatasi yasamadan once programin kullanimiyla ilgili bilgi alacaksin.

strftime'a gerek olmadigi dogru ama normalde zaten varsa kutuphane olanaklari kullanilir. Onlar uzmanlar tarafindan yazilip duzeltilmis ve milyonlarca programda denenmis saglam fonksiyonlardir.

Ali