added support for more planets and the earth's moon

This commit is contained in:
Steffen Vogel 2013-02-07 16:29:36 +01:00
parent 58463813cb
commit 2dca19e6f9
6 changed files with 378 additions and 86 deletions

View file

@ -1,6 +1,6 @@
bin_PROGRAMS = sun
sun_SOURCES = sun_main.c
sun_SOURCES = sun_main.c objects.c
sun_LDADD = -lm -lnova
if GEONAMES_SUPPORT

View file

@ -71,9 +71,9 @@ am__geonames_SOURCES_DIST = geonames_main.c geonames.c
geonames_OBJECTS = $(am_geonames_OBJECTS)
am__DEPENDENCIES_1 =
@GEONAMES_SUPPORT_TRUE@geonames_DEPENDENCIES = $(am__DEPENDENCIES_1)
am__sun_SOURCES_DIST = sun_main.c geonames.c
am__sun_SOURCES_DIST = sun_main.c objects.c geonames.c
@GEONAMES_SUPPORT_TRUE@am__objects_1 = geonames.$(OBJEXT)
am_sun_OBJECTS = sun_main.$(OBJEXT) $(am__objects_1)
am_sun_OBJECTS = sun_main.$(OBJEXT) objects.$(OBJEXT) $(am__objects_1)
sun_OBJECTS = $(am_sun_OBJECTS)
@GEONAMES_SUPPORT_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
sun_DEPENDENCIES = $(am__DEPENDENCIES_2)
@ -183,7 +183,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
sun_SOURCES = sun_main.c $(am__append_1)
sun_SOURCES = sun_main.c objects.c $(am__append_1)
sun_LDADD = -lm -lnova $(am__append_2)
@GEONAMES_SUPPORT_TRUE@geonames_SOURCES = geonames_main.c geonames.c
@GEONAMES_SUPPORT_TRUE@geonames_LDADD = $(DEPS_GEONAMES_LIBS)
@ -280,6 +280,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geonames.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geonames_main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objects.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sun_main.Po@am__quote@
.c.o:

View file

@ -44,7 +44,7 @@ int main(int argc, char *argv[]) {
int ret = geonames_lookup(name, &res, result_name, 32);
if (ret == EXIT_SUCCESS) {
printf("%s is at (%.4f, %.4f)\r\n", result_name, res.lat, res.lon);
printf("%s is at (%.4f, %.4f)\r\n", result_name, res.lat, res.lng);
}
free(result_name);

166
src/objects.c Normal file
View file

@ -0,0 +1,166 @@
/**
* libnova bindings
*
* @copyright 2012 Steffen Vogel
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Steffen Vogel <post@steffenvogel.de>
* @link http://www.steffenvogel.de/2012/03/14/cron-jobs-fur-sonnenauf-untergang/
*/
/*
* This file is part of sun
*
* sun is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* sun is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sun. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libnova/solar.h>
#include <libnova/mars.h>
#include <libnova/lunar.h>
#include <libnova/neptune.h>
#include <libnova/jupiter.h>
#include <libnova/mercury.h>
#include <libnova/uranus.h>
#include <libnova/saturn.h>
#include <libnova/venus.h>
#include <libnova/pluto.h>
#include <libnova/earth.h>
#include <string.h>
#include "objects.h"
void object_pos(enum object obj, double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
switch (obj) {
case OBJECT_SUN: return object_pos_sun(jd, obs, equ, hrz, diam, dist);
case OBJECT_MOON: return object_pos_moon(jd, obs, equ, hrz, diam, dist);
case OBJECT_MARS: return object_pos_mars(jd, obs, equ, hrz, diam, dist);
case OBJECT_NEPTUNE: return object_pos_neptune(jd, obs, equ, hrz, diam, dist);
case OBJECT_JUPITER: return object_pos_jupiter(jd, obs, equ, hrz, diam, dist);
case OBJECT_MERCURY: return object_pos_mercury(jd, obs, equ, hrz, diam, dist);
case OBJECT_URANUS: return object_pos_uranus(jd, obs, equ, hrz, diam, dist);
case OBJECT_SATURN: return object_pos_saturn(jd, obs, equ, hrz, diam, dist);
case OBJECT_VENUS: return object_pos_venus(jd, obs, equ, hrz, diam, dist);
case OBJECT_PLUTO: return object_pos_pluto(jd, obs, equ, hrz, diam, dist);
}
}
int object_rst(enum object obj, double jd, double horizon, struct ln_lnlat_posn *obs, struct ln_rst_time *rst) {
switch (obj) {
case OBJECT_SUN: return ln_get_solar_rst_horizon(jd, obs, horizon, rst);
case OBJECT_MOON: return ln_get_lunar_rst(jd, obs, rst);
case OBJECT_MARS: return ln_get_mars_rst(jd, obs, rst);
case OBJECT_NEPTUNE: return ln_get_neptune_rst(jd, obs, rst);
case OBJECT_JUPITER: return ln_get_jupiter_rst(jd, obs, rst);
case OBJECT_MERCURY: return ln_get_mercury_rst(jd, obs, rst);
case OBJECT_URANUS: return ln_get_uranus_rst(jd, obs, rst);
case OBJECT_SATURN: return ln_get_saturn_rst(jd, obs, rst);
case OBJECT_VENUS: return ln_get_venus_rst(jd, obs, rst);
case OBJECT_PLUTO: return ln_get_pluto_rst(jd, obs, rst);
}
}
enum object object_from_name(const char *name, bool casesen) {
// TODO case sensivity
if (strcmp(name, "sun") == 0) return OBJECT_SUN;
else if (strcmp(name, "moon") == 0) return OBJECT_MOON;
else if (strcmp(name, "mars") == 0) return OBJECT_MARS;
else if (strcmp(name, "neptune") == 0) return OBJECT_NEPTUNE;
else if (strcmp(name, "jupiter") == 0) return OBJECT_JUPITER;
else if (strcmp(name, "mercury") == 0) return OBJECT_MERCURY;
else if (strcmp(name, "uranus") == 0) return OBJECT_URANUS;
else if (strcmp(name, "saturn") == 0) return OBJECT_SATURN;
else if (strcmp(name, "venus") == 0) return OBJECT_VENUS;
else if (strcmp(name, "pluto") == 0) return OBJECT_PLUTO;
else return OBJECT_INVALID;
}
void object_pos_sun(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_solar_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_earth_solar_dist(jd);
*diam = ln_get_solar_sdiam(jd);
}
void object_pos_moon(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_lunar_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_lunar_earth_dist(jd) / AU_METERS;
*diam = ln_get_lunar_sdiam(jd);
}
void object_pos_mars(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_mars_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_mars_earth_dist(jd);
*diam = ln_get_mars_sdiam(jd);
}
void object_pos_neptune(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_neptune_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_neptune_earth_dist(jd);
*diam = ln_get_neptune_sdiam(jd);
}
void object_pos_jupiter(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_jupiter_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_jupiter_earth_dist(jd);
*diam = ln_get_jupiter_equ_sdiam(jd);
}
void object_pos_mercury(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_mercury_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_mercury_earth_dist(jd);
*diam = ln_get_mercury_sdiam(jd);
}
void object_pos_uranus(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_uranus_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_uranus_earth_dist(jd);
*diam = ln_get_uranus_sdiam(jd);
}
void object_pos_saturn(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_saturn_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_saturn_earth_dist(jd);
*diam = ln_get_saturn_equ_sdiam(jd);
}
void object_pos_venus(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_venus_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_venus_earth_dist(jd);
*diam = ln_get_venus_sdiam(jd);
}
void object_pos_pluto(double jd, struct ln_lnlat_posn *obs, struct ln_equ_posn *equ, struct ln_hrz_posn *hrz, double *diam, double *dist) {
ln_get_pluto_equ_coords(jd, equ);
ln_get_hrz_from_equ(equ, obs, jd, hrz);
*dist = ln_get_pluto_earth_dist(jd);
*diam = ln_get_pluto_sdiam(jd);
}

75
src/objects.h Normal file
View file

@ -0,0 +1,75 @@
/**
* libnova bindings
*
* @copyright 2012 Steffen Vogel
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Steffen Vogel <post@steffenvogel.de>
* @link http://www.steffenvogel.de/2012/03/14/cron-jobs-fur-sonnenauf-untergang/
*/
/*
* This file is part of sun
*
* sun is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* sun is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sun. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _OBJECTS_H_
#define _OBJECTS_H_
#include <libnova/ln_types.h>
#include <stdbool.h>
#define AU_METERS 149597870.7
enum object {
OBJECT_INVALID,
OBJECT_SUN,
OBJECT_MOON,
OBJECT_MARS,
OBJECT_NEPTUNE,
OBJECT_JUPITER,
OBJECT_MERCURY,
OBJECT_URANUS,
OBJECT_SATURN,
OBJECT_VENUS,
OBJECT_PLUTO
};
struct object_infos {
struct ln_rst_time *rst;
struct ln_lnlat_posn *obs;
struct ln_equ_posn *equ;
struct ln_hrz_posn *hrz;
double *diam;
double *dist;
};
enum object object_from_name(const char *name, bool casesen);
void object_pos(enum object obj, double jd, struct object_details *details);
int object_rst(enum object obj, double jd, double horizon, struct ln_lnlat_posn *obs, struct ln_rst_time *rst);
void object_pos_sun(double jd, struct object_details *details);
void object_pos_moon(double jd, struct object_details *details);
void object_pos_mars(double jd, struct object_details *details);
void object_pos_neptune(double jd, struct object_details *details);
void object_pos_jupiter(double jd, struct object_details *details);
void object_pos_mercury(double jd, struct object_details *details);
void object_pos_uranus(double jd, struct object_details *details);
void object_pos_saturn(double jd, struct object_details *details);
void object_pos_venus(double jd, struct object_details *details);
void object_pos_pluto(double jd, struct object_details *details);
#endif /* _OBJECTS_H_ */

View file

@ -39,34 +39,46 @@
#include <time.h>
#include <sys/time.h>
#include <libgen.h>
#include <libnova/libnova.h>
#include <libnova/solar.h>
#include <libnova/utility.h>
#include "../config.h"
#include "objects.h"
enum mode { INVALID, RISE, SET, TRANSIT, DAYTIME, NIGHTTIME };
enum mode {
MODE_NOW,
MODE_RISE,
MODE_SET,
MODE_TRANSIT
};
extern long timezone;
static struct option long_options[] = {
{"horizon", required_argument, 0, 't'},
{"date", required_argument, 0, 'd'},
{"object", required_argument, 0, 'p'},
{"horizon", required_argument, 0, 'H'},
{"time", required_argument, 0, 't'},
{"moment", required_argument, 0, 'm'},
{"format", required_argument, 0, 'f'},
{"lat", required_argument, 0, 'a'},
{"lon", required_argument, 0, 'o'},
#ifdef GEONAMES_SUPPORT
{"query", required_argument, 0, 'q'},
#endif
{"zone", required_argument, 0, 'z'},
{"timezone", required_argument, 0, 'z'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{0}
};
static char *long_options_descs[] = {
"use special twilight (nautic|civil|astronomical)",
"calculcate for specified date (eg. 2011-12-25)",
"output format (eg. %H:%M:%S)",
"calculate for given object/planet",
"calculate rise/set with given twilight (nautic|civil|astronomical)",
"calculate with given time (eg. 2011-12-25)",
"use rise/set/transit time for position calculation",
"output format (see strftime (3))",
"geographical latitude (-90° to 90°)",
"geographical longitude (-180° to 180°)",
#ifdef GEONAMES_SUPPORT
@ -83,8 +95,7 @@ void version () {
}
void usage() {
printf("Usage:\n sun mode [options]\n\n");
printf(" mode is one of: rise, set, transit, daytime, nighttime\n\n");
printf("Usage:\n %s [options]\n\n", PACKAGE_NAME);
printf("Options:\n");
struct option *op = long_options;
@ -133,41 +144,32 @@ int main(int argc, char *argv[]) {
char *query = NULL;
bool error = false;
enum mode mode = INVALID;
enum mode mode = MODE_NOW;
enum object obj = OBJECT_INVALID;
double julian;
double jd;
struct tm date = { 0 };
struct ln_rst_time rst;
struct ln_lnlat_posn observer = { DBL_MAX, DBL_MAX };
struct ln_lnlat_posn obs = { DBL_MAX, DBL_MAX };
tzset();
/* default time: now */
julian = ln_get_julian_from_sys();
jd = ln_get_julian_from_sys();
/* parse mode */
if (argc > 1 && argv[1][0] != '-') {
if (strcmp(argv[1], "rise") == 0) mode = RISE;
else if (strcmp(argv[1], "set") == 0) mode = SET;
else if (strcmp(argv[1], "transit") == 0) mode = TRANSIT;
else if (strcmp(argv[1], "daytime") == 0) mode = DAYTIME;
else if (strcmp(argv[1], "nighttime") == 0) mode = NIGHTTIME;
/* skip mode parameter for following getopt() */
argc--;
argv++;
}
/* parse planet/obj */
obj = object_from_name(basename(argv[0]), false);
/* parse command line arguments */
while (1) {
int optidx;
int c = getopt_long(argc, argv, "+hvt:d:f:a:o:q:z:", long_options, &optidx);
int c = getopt_long(argc, argv, "+hvt:d:f:a:o:q:z:p:", long_options, &optidx);
/* detect the end of the options. */
if (c == -1) break;
switch (c) {
case 't':
case 'H':
if (strcmp(optarg, "civil") == 0) {
horizon = LN_SOLAR_CIVIL_HORIZON;
}
@ -183,14 +185,14 @@ int main(int argc, char *argv[]) {
}
break;
case 'd':
case 't':
if (strptime(optarg, "%Y-%m-%d", &date) == NULL) {
fprintf(stderr, "invalid date: %s\n", optarg);
error = true;
}
else {
time_t t = mktime(&date);
julian = ln_get_julian_from_timet(&t);
jd = ln_get_julian_from_timet(&t);
#ifdef DEBUG
char date_str[64];
@ -201,16 +203,27 @@ int main(int argc, char *argv[]) {
}
break;
case 'm':
if (strcmp(optarg, "now") == 0) mode = MODE_NOW;
else if (strcmp(optarg, "rise") == 0) mode = MODE_RISE;
else if (strcmp(optarg, "set") == 0) mode = MODE_SET;
else if (strcmp(optarg, "transit") == 0) mode = MODE_TRANSIT;
else {
fprintf(stderr, "invalid moment: %s\n", optarg);
error = true;
}
break;
case 'f':
format = strdup(optarg);
break;
case 'a':
observer.lat = strtod(optarg, NULL);
obs.lat = strtod(optarg, NULL);
break;
case 'o':
observer.lng = strtod(optarg, NULL);
obs.lng = strtod(optarg, NULL);
break;
#ifdef GEONAMES_SUPPORT
case 'q':
@ -218,6 +231,10 @@ int main(int argc, char *argv[]) {
break;
#endif
case 'p':
obj = object_from_name(optarg, false);
break;
case 'z':
timezone = -3600 * atoi(optarg);
break;
@ -237,26 +254,26 @@ int main(int argc, char *argv[]) {
}
}
/* validate mode */
if (mode == INVALID) {
fprintf(stderr, "invalid mode\n");
/* validate obj */
if (obj == OBJECT_INVALID) {
fprintf(stderr, "invalid object\n");
error = true;
}
#ifdef GEONAMES_SUPPORT
/* lookup place at http://geonames.org */
if (query && geonames_lookup(query, (struct pos *) &observer, NULL, 0) != 0) {
if (query && geonames_lookup(query, (struct pos *) &obs, NULL, 0) != 0) {
fprintf(stderr, "failed to lookup location: %s\n", query);
error = true;
}
#endif
/* validate coordinates */
if (fabs(observer.lat) > 90) {
/* validate observer coordinates */
if (fabs(obs.lat) > 90) {
fprintf(stderr, "invalid latitude\n");
error = true;
}
if (fabs(observer.lng) > 180) {
if (fabs(obs.lng) > 180) {
fprintf(stderr, "invalid longitude\n");
error = true;
}
@ -271,62 +288,95 @@ int main(int argc, char *argv[]) {
#ifdef DEBUG
char date_str[64];
time_t t;
ln_get_timet_from_julian(julian, &t);
ln_get_timet_from_julian(jd, &t);
strftime(date_str, 64, "%Y-%m-%d", gmtime(&t));
strftime(date_str, 64, "%Y-%m-%d %H:%M:%S", gmtime(&t));
printf("calculate for: %s\n", date_str);
printf("for position: %f, %f\n", observer.lat, observer.lng);
printf("calculate for jd: %f\n", jd);
printf("for position: %f, %f\n", obs.lat, obs.lng);
printf("for object: %d\n", obj);
printf("with horizon: %f\n", horizon);
printf("with timezone: UTC +%dh\n", timezone / -3600);
#endif
if (ln_get_solar_rst_horizon(julian, &observer, horizon, &rst) == 1) {
fprintf(stderr, "sun is circumpolar\n");
char result_str[64];
struct tm result_date;
struct ln_date result_ln;
if (object_rst(obj, jd, horizon, &obs, &rst) == 1) {
fprintf(stderr, "object is circumpolar\n");
return EXIT_CIRCUMPOLAR;
}
switch (mode) {
case MODE_RISE: jd = rst.rise; break;
case MODE_SET: jd = rst.set; break;
case MODE_TRANSIT: jd = rst.transit; break;
case MODE_DAYTIME: jd = rst.set - rst.rise; break;
case MODE_NIGHTTIME: jd = rst.set - rst.rise; break;
case MODE_INVALID: break;
}
if (mode == MODE_DAYTIME || mode == MODE_NIGHTTIME) {
ln_get_date(jd - 0.5, &result_ln);
if (strstr(format, "%s") != NULL) {
char timestamp_str[16];
int seconds = round(jd * 86400);
snprintf(timestamp_str, sizeof(timestamp_str), "%lu", seconds);
format = strreplace(format, "%s", timestamp_str);
}
result_date.tm_year = -1900;
result_date.tm_mon = -1;
result_date.tm_mday = 0;
}
else {
double result_jd;
char result_str[64];
struct tm result_date;
struct ln_date result_ln;
// calculate position
struct ln_equ_posn result_equ;
struct ln_hrz_posn result_hrz;
double result_dist;
double result_diam;
switch (mode) {
case RISE: result_jd = rst.rise; break;
case SET: result_jd = rst.set; break;
case TRANSIT: result_jd = rst.transit; break;
case DAYTIME: result_jd = rst.set - rst.rise; break;
case NIGHTTIME: result_jd = rst.set - rst.rise; break;
object_pos(obj, jd, &obs, &result_equ, &result_hrz, &result_diam, &result_dist);
struct ln_hms ra;
ln_deg_to_hms(result_equ.ra, &ra);
double az = result_hrz.az + 180;
az -= (int) (az / 360) * 360;
printf("diam = %f\n", result_diam);
printf("dist au = %f\n", result_dist);
printf("dist km = %f\n", AU_METERS * result_dist);
printf("az = %s\n", ln_get_humanr_location(az));
printf("alt = %s\n", ln_get_humanr_location(result_hrz.alt));
printf("ra = %dh%dm%fs\n", ra.hours, ra.minutes, ra.seconds);
printf("dec = %s\n", ln_get_humanr_location(result_equ.dec));
/*if (strstr(format, "%R") != NULL) {
snprintf(timestamp_str, sizeof(timestamp_str), "%lu", seconds);
format = strreplace(format, "%s", timestamp_str);
}
if (strstr(format, "%E") != NULL) {
snprintf(timestamp_str, sizeof(timestamp_str), "%lu", seconds);
format = strreplace(format, "%s", timestamp_str);
}*/
if (mode == DAYTIME || mode == NIGHTTIME) {
ln_get_date(result_jd - 0.5, &result_ln);
ln_get_date(jd - timezone / 86400.0, &result_ln);
if (strstr(format, "%s") != NULL) {
char timestamp_str[16];
int seconds = round(result_jd * 86400);
snprintf(timestamp_str, sizeof(timestamp_str), "%lu", seconds);
format = strreplace(format, "%s", timestamp_str);
}
result_date.tm_year = result_ln.years - 1900;
result_date.tm_mon = result_ln.months - 1;
result_date.tm_mday = result_ln.days;
}
result_date.tm_year = -1900;
result_date.tm_mon = -1;
result_date.tm_mday = 0;
}
else {
ln_get_date(result_jd - timezone / 86400.0, &result_ln);
result_date.tm_hour = result_ln.hours;
result_date.tm_min = result_ln.minutes;
result_date.tm_sec = result_ln.seconds;
result_date.tm_year = result_ln.years - 1900;
result_date.tm_mon = result_ln.months - 1;
result_date.tm_mday = result_ln.days;
}
strftime(result_str, 64, format, &result_date);
printf("%s\n", result_str);
result_date.tm_hour = result_ln.hours;
result_date.tm_min = result_ln.minutes;
result_date.tm_sec = result_ln.seconds;
strftime(result_str, 64, format, &result_date);
printf("%s\n", result_str);
return EXIT_SUCCESS;
}
return EXIT_SUCCESS;
}