How to set the timezone permanently in ubuntu using C program - c

When i write -
root#XYZ:/home/timez# export TZ=UTC; date
Thu Nov 13 05:35:36 UTC 2014
It change the date & timezone. I want a equivalent C program of this.
I wrote a C program to set Timezone in my Ubuntu machine using code -
system(" export TZ=CST6CDT; date ");
i can see the date in CST as output but this program is not setting Ubuntu Timezone to CST, it is still in UTC.

There exists a settimeofday call inherited from Unix V7 or even before ... that used to set a time zone value in the kernel. But my current man says now : Note: timezone is no longer used; this information is kept outside the kernel.
So in system less than 20 years old, the time zone is only kept in the environment. And the environment has the following property :
a child inherit the environment of its parent but cannot modify its parent's environment
That means that any C program can modify its TZ via a simple setenv call, and this new timezone will be used by itself and all its childs, but it will never be able to modify the environment of the shell that started it. The only possibility would be a special API offered by shell programs, but I know none that implements such a thing.
I know it is a you can't answer but it is the best I can do ...

Related

Dart - How can I get the creationTime of a File?

I need to get the creationTime of a File in my Flutter project but all I have from a File object is lastModified() and lastAccessed(), no trace of a method to get the DateTime of creation.
I see that in Java it is possible: https://stackoverflow.com/a/2724009/3997782
and also in Swift: https://stackoverflow.com/a/6428757/3997782
I could use the Flutter MethodChannel function to get that but I would like to know if there a native Dart way to get it.
How to get the local file information, such as file creation time
Not all platforms does have a concept of file creation time. E.g. Linux does not for all file systems and the general stat() call does not provide that information.
That does not mean you cannot access what seems to be creation time. But you should not necessarily trust its value which are also documented in the Java API:
Returns the creation time. The creation time is the time that the file was created.
If the file system implementation does not support a time stamp to indicate the time when the file was created then this method returns an implementation specific default value, typically the last-modified-time or a FileTime representing the epoch (1970-01-01T00:00:00Z).
https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/BasicFileAttributes.html#creationTime()
Dart does have a similar API if you use the FileStat class which have this property:
DateTime changed
The time of the last change to the data or metadata of the file system object.
On Windows platforms, this is instead the file creation time.
https://api.dart.dev/stable/2.7.2/dart-io/FileStat/changed.html
But the data for FileStat is documented to come from the POSIX stat() system call which does not have a concept of creation timestamp of files but has the following:
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
Which maps to the three timestamps you can get from FileStat:
import "dart:io";
main() {
final stat = FileStat.statSync("test.dart");
print('Accessed: ${stat.accessed}');
print('Modified: ${stat.modified}');
print('Changed: ${stat.changed}');
}
But as you can see on Linux with XFS it will return the same value for changed and modified:
[julemand101#beta ~]$ dart test.dart
Accessed: 2020-04-07 18:19:20.404
Modified: 2020-04-07 18:19:19.020
Changed: 2020-04-07 18:19:19.020
You can get a different changed time if you e.g. update inode information:
[julemand101#beta ~]$ chmod +x test.dart
[julemand101#beta ~]$ dart test.dart
Accessed: 2020-04-07 18:19:42.341
Modified: 2020-04-07 18:19:19.020
Changed: 2020-04-07 18:19:39.397
Which makes sense since the st_ctime is documented as:
The field st_ctime is changed by writing or by setting inode information (i.e., owner, group, link count, mode, etc.).
https://linux.die.net/man/2/stat
So in short, you should try and see what happens for iOS and Android when using FileStat. But in short, it is difficult to write a platform independent API which gives access to differences at each platform. Especially for a platform like Linux where it is up to each file system if a feature exists or not.

C program delivers only the UTC time as localtime on Linux using GCC

I have a C program that runs on two different RHEL6 servers that are configured with the same timezone. The C program uses the time functions from time.h. On one of the servers the local time is correctly determined, on the other one the UTC (default) time is displayed independent from the configured timezone.
I've tried to see if the link to /etc/localtime is broken but it's a correct softlink to /usr/share/zoneinfo/<timezone> (in this case Europe/Berlin).
I've inspected the timezone file with zdump and the content of the file is correct. The timezone and time of the system is also correctly displayed using date. There is no definition of the $TZ variable in my bash or anywhere else!
As an additional test I have run the follwing code with and without a $TZ variable:
::time_t aclock;
::tm tm_tmp;
::tm *newtime;
setenv("TZ", "Europe/Berlin", 1);
tzset();
::time( &aclock );
newtime = ::localtime_r( &aclock, &tm_tmp );
printf("\nDEBUG TIME: %d ", aclock);
printf("\nDEBUG TIMEZONE: %s \n", newtime->tm_zone);
printf("DEBUG HOUR: %d \n", newtime->tm_hour);
Using the code above and setting TZ parameter differently I get the following outputs on the faulty server, assuming that the server time is Europe/Berlin, CEST at this moment:
without setenv:
DEBUG TIME: 1524241319
DEBUG TIMEZONE: UTC
DEBUG HOUR: 16
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: Europe
DEBUG HOUR: 16
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241319
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
So it looks like the "Europe/Berlin" time cannot be found, as the UTC time is displayed and the timezone "Europe" is invalid.
As I said the output / behavior on the other machine is the expected one:
without setenv:
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "Europe/Berlin", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
setenv("TZ", "/etc/localtime", 1);
DEBUG TIME: 1524241711
DEBUG TIMEZONE: CEST
DEBUG HOUR: 18
P.S. the same gcc version 4.4.7 is used on both machines.
Is it possible that my timezone database is corrupt on the faulty server? Has someone faced similar problem and solve it?
I finally figured out, that the problem was the libc.so library, which was differently compiled for one of the machines and only used for some C applications excepting linux himself. This explains why date delivers the wright output but the C program not.
Using ldd libc.so I've found out that the linker was also set to be at the path /home/mqm/lib as default, which dosn't fit to my server /home/mqm/lib/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2. To resume, here is the full solution:
Problem: Your Linux system is delivering the wright date and time using date or some applications but wrong output using C programs.
Solution: After ensuring that there is no programming error in your code, check with
strace -e trace=open,close,read,write,connect,accept yourCProgram
which path is used to get the time/timezone. You can also check ldd libc.so to see where the default path of the linker is.
If the paths are not corresponding to your linux system configuration, consider recompiling the C library to fit to your system configuration or set $TZ='fullpathtotimezone' as a hotfix / workaround.

How can I get last modified timestamp in Lua

I am trying to work on Lua file handling.
So, I am able to open, read, write, close the files.
local session_debug = io.open("/root/session_debug.txt", "a")
session_debug:write("Some text\n")
session_debug:close()
How can I know the last modified date timestamp of this file.
There's no built-in function in standard Lua that does this. One way to get it without third-party libraries is to take use of io.popen.
For example, on Linux, you could use stat:
local f = io.popen("stat -c %Y testfile")
local last_modified = f:read()
Now last_modified is the timestamp of the last modified time of testfile. On my system,
print(os.date("%c", last_modified))
Outputs Sat Mar 22 08:36:50 2014.
If you don't mind using a library, LuaFileSystem allows you to get the modified timestamp as follows:
local t = lfs.attributes(path, 'modification')
A more elaborate example with error handling (will print the name and date of modification of the first argument passed to the script):
local lfs = require('lfs')
local time, err = lfs.attributes(arg[1], 'modification')
if err then
print(err)
else
print(arg[1], os.date("%c", time))
end

Where does the timezone for date and strftime come from?

Im curious because I checked on a linux host in Sydney, Australia and the date command says EST as the timezone, as does strftime(tz, sizeof(tz), "%Z", &time) when running a simple C binary to print that out. However, I know the timezone is AEST. Are timezone abbreviations truncated? Where can I find out more about this?
Australian time zone abbreviations changed in tzdb 2014f, released in August 2014.
You simply need to update your time zone data file to the current version (2015b as of this writing). On linux, this is usually in the tzdata package, which you can update using apt-get, or rpm, or whatever is appropriate for your distro.
the current timezone is typically in an environment variable and/or in a special file in /etc/ in linux

DST restoration under Linux in C

I have date/time information from Berlin,Germany.
For example:
2011-05-16 12:24:23,
2011-01-21 17:00:31
Unfortunatly, these times have NO daylight saving information. I know that the first date is CEST and the second time is CET.
I could write a check whether the date/time is daylight saving or not.
The summertime starts at the last sunday in march at 2:00 AM, and ends at the last sunday in october at 3 AM.
Self developing such a check seems error prone to me. Is there something that can be already used under Linux in C?
Thank you for your help.
You can convert the time to a time_t with mktime() and then pass it back in to localtime() which will set tm_isdst. Both mktime() and localtime() utilize your local system's time configuration, so you're really discovering if the timestamp is in DST where you are. The obvious problem here is that you have a timestamp string without geographical information so the best you can do is assume it's for your current location.
You can pass the %Z format argument to the date command to obtain the timezone from a date, then determine if DST was in effect from the timezone's name:
$ date -d '2011-05-16' '+%Z'
CEST
$ date -d '2011-01-21' '+%Z'
CET

Resources