IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Reformater une date


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2012
    Messages : 56
    Par défaut Reformater une date
    Bonjour à tous,

    Je recherche une méthode simple et efficace pour reformater une date en C++ avec un std::string en entrée.

    Exemple:
    Format initial: YYYYMMDD-H24MiSS
    Format voulu: YYYYMMDDH24

    Beaucoup de fonction comme std::put_time attendent un objet tm visiblement,
    Après, je pourrais utiliser un équivalent C++ des scanf & sprintf, mais il existe sûrement d'autres alternatives, des idées?

    Merci.

  2. #2
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Un très vieux code extait de mes arrchives.
    A adapter pour tes besoins
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    template<typename C, typename Tr, typename Al>
    inline void concat_sep(std::basic_string<C, Tr, Al> & s,
    	std::basic_string<C, Tr, Al> const & str,
    	C const *sep, typename std::basic_string<C, Tr, Al>::size_type seplen,
    	C prefix=0, C suffix=0)
    {
    	if (!str.empty())
    	{
    		if (!s.empty())
    			s.append(sep, seplen);
    		if (prefix != 0)
    			s+=prefix;
    		s+=str;
    		if (suffix != 0)
    			s+=suffix;
    	}
    }
     
    // if date is "YYYY/MM/DD" then function returns "Month DD, YYYY"
    // if date is "YYYY/MM" then function returns "Month YYYY"
    std::string StringDate(std::string const & date)
    {
    	static const char *strmonth[]=
    		{"January","February","March","April","May","June"
    		,"July","August","September","October","November","December"};
    	std::string strdate;
    	const char *yearsep;
    	{
    	std::string month(date.substr(5,2));
    	unsigned m=string2ui(month);
    	if (1<=m && m<=12)
    		strdate+=strmonth[m-1];
    	}
    	if (date.length()==10)
    	{
    		std::string day(date.substr(8,2));
    		char d=day[1u];
    		//if (day.length()==2 && '0'<=d && d<='9')
    		{
    			strdate+=' ';
    			if (day[0u]<='0')
    				strdate+=d;
    			else
    				strdate+=day;
    			yearsep=", ";
    		}
    	}
    	else
    		yearsep=" ";
    	concat_sep(strdate,date.substr(0,4),yearsep,std::char_traits<char>::length(yearsep));// same as strlen(yearsep) !
    	return strdate;
    }
     
     
    std::string FormatDate(std::string & start)
    {
    	//start is modified into YYYY, YYYY/MM or YYYY/MM/DD
    	std::string formated;
    	if (start.length()==4)
    		formated=start;
    	else if (start.substr(0,2)=="//")
    		formated=start=start.substr(2,4);
    	else if (start.substr(0,6)=="00/00/")
    		formated=start=start.substr(6,4);
    	else if (start.length()==10 && start.substr(2,4)=="/00/")
    		formated=StringDate(start=start.substr(6,4)+'/'+start.substr(0,2));
    	else if (start.length()==8 && start.substr(2,2)=="//")
    		formated=StringDate(start=start.substr(4,4)+'/'+start.substr(0,2));
    	else if (start.length()==10 && start[2u]=='/' && start[5u]=='/')
    		formated=StringDate(start=start.substr(6,4)+'/'+start.substr(0,3)+start.substr(3,2));
    	else if (start.length()==7 && start[2u]=='/')
    		formated=StringDate(start=start.substr(3,4)+'/'+start.substr(0,2));
    	return formated;
    }

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Hello

    Pour faire ce genre de chose, j'aime beaucoup la bibliothèque fmt. Une solution, avec un mix de la réponse de bacelar :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <string>
    #include <iostream>
    #include <iomanip>
    #include <sstream>
    #include <ctime>
    #include "fmt/time.h"
     
    int main(void) {
        // Parse existing string
        std::tm tm = {};
        std::stringstream ss("20140109-123534");
        ss >> std::get_time(&tm, "%Y%m%d-%H%M%S");
     
        // Format it back
        std::string date_str = fmt::format("{:%Y%0m%0d%H}", tm);
     
        // Print result for the show
        std::cout << date_str << std::endl;
        return 0;
    }
    Ici j'ai utilisé fmt::format(...) pour l'exemple mais si tu dump dans un fichier ou un stream, une autre API de fmt peut s'avérer plus pertinente. Peut-être que std::put_time te suffira si tu ne veux pas la dépendance.

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    En temps normal, j'utilise strptime (comprendre: je suis dans un environnement *nix quasi tout le temps).
    Si tu as accès au C++11, std::get_time parait bien -- je ne vois pas d'évolution pour std::string_view en C++17, dommage.
    Et vu que j'ai eu besoin d'avoir un truc minimaliste pour du portable en C++98, j'ai pondu ça il y a peu (LGPL).

    Mais ... vu les specs, une simple manipulation de caractères semble pouvoir faire l'affaire. Même pas besoin de décoder quoi que ce soit. Ca ressemble à un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %s/(\d{8})-(\d{2})\d{4}/\1\2
    (regex à adapter au moteur de regex utilisé)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 151
    Billets dans le blog
    4
    Par défaut
    Si le format est aussi simple et fixe que dans le poste initial, je me contenterai de retirer les 4 derniers caractères (MiSS) et le '-' du milieu d'un simple str.erase(8,1).erase(11)
    8:1 retire le -
    11 est la position après retrait du - des MiSS
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #6
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Commence par retirer la fin, cela évitera de la dupliquer pour rien.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. [XL-2010] Comment reformater une date ?
    Par juju05 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 27/11/2014, 17h06
  2. Récupérer l'année d'une date
    Par delphim dans le forum Langage SQL
    Réponses: 3
    Dernier message: 15/01/2003, 16h33
  3. tester si une date est valide
    Par Andry dans le forum Langage
    Réponses: 5
    Dernier message: 17/09/2002, 11h54
  4. Generation d'evenements a une date precise
    Par pascalzzz dans le forum MFC
    Réponses: 2
    Dernier message: 04/06/2002, 15h21
  5. Réponses: 3
    Dernier message: 19/04/2002, 00h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo