How do I print a Poco::Timestamp with Poco::DateTimeFormatter into a formatted date-time based on the current timezone?
I have a print_pretty_datetime(const Poco::Timestamp &now) where I'll receive a Poco::Timestamp so I can't use a Poco::LocalDateTime unfortunately.
MCVE:
#include "Poco/Timestamp.h"
#include "Poco/Timezone.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include <iostream>
#include <string>
// Cannot change the method signature. I will receive a Poco::Timestamp object
std::string print_pretty_datetime(const Poco::Timestamp &now)
{
return Poco::DateTimeFormatter::format(
now,
Poco::DateTimeFormat::SORTABLE_FORMAT,
Poco::Timezone::tzd()
);
}
int main()
{
Poco::Timestamp now;
std::string dt_now = print_pretty_datetime(now);
std::cout << dt_now << '\n';
return 0;
}
E.g: the string returned is 2019-01-07 11:10:12 (thus UTC+0) whereas my device is in in UTC+1.
In fact, the command date returns Mon Jan 7 12.10.12 CET 2019.
What is the correct parameter for tzd in Poco::DateTimeFormatter::format for printing the date-time based on current locale?
System info:
SMP Debian 4.9.130-2 (2018-10-27) x86_64 GNU/Linux
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Poco 1.9.0
Get local time by Poco::LocalDateTime, then read its timestemp and pass it into formatter:
Poco::LocalDateTime dateTime;
Poco::Timestamp now = dateTime.timestamp();
You need to define your own string format which includes information about time-zone, because SORTABLE_FORMAT doesn't handle it.
Hint (you can open source of DateTimeFormatter and see how timeZoneDifferential is processed in append function - this parameter doesn't affect hours in output).
So if you change to:
std::string dt_now = Poco::DateTimeFormatter::format(
now,
"%H:%M:%S %z,%Z",
Poco::Timezone::tzd()
);
you will see HH::MM::SS +01:00,+0100 in output.
You can create a Poco::LocalDateTime in the system's current timezone from a Poco::Timestamp via an intermediate Poco::DateTime object.
#include "Poco/LocalDateTime.h"
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
#include <iostream>
int main(int argc, char** argv)
{
Poco::Timestamp ts;
Poco::DateTime dt(ts);
Poco::LocalDateTime ldt(dt);
std::string str = Poco::DateTimeFormatter::format(ldt, Poco::DateTimeFormat::SORTABLE_FORMAT);
std::cout << str << std::endl;
return 0;
}
Alright, if you don't necessarily need to use a Poco::Timestamp, a solution can be simply to use a Poco::LocalDateTime:
#include "Poco/LocalDateTime.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include <iostream>
#include <string>
int main()
{
Poco::LocalDateTime now;
std::string dt_now = Poco::DateTimeFormatter::format(
now,
Poco::DateTimeFormat::SORTABLE_FORMAT
);
std::cout << dt_now << '\n';
return 0;
}
and this will print the date based on the current timezone.
I still have to use the Poco::Timestamp though as I'll get it as parameter to my print_pretty_datetime(const pc::Timestamp &now), so this answer does not yet applies to my case.
Related
I'm trying to get ru locale on OS without one.
I try to get it from icu using boost::locale::generator. Test program is simple I get locale (success) and then I check if russian letter is alphabetical character (fails). What am I doing wrong?
Here is the code:
#include <iostream>
#include <boost/locale.hpp>
#include <boost/locale/localization_backend.hpp>
using namespace std;
int main()
{
using namespace boost::locale;
localization_backend_manager my = localization_backend_manager::global();
my.select("icu");
boost::locale::generator gen(my);
std::locale loc( gen.generate( "ru_RU.UTF-8" ) );
if( !std::isalpha( L'ф', loc ) )
std::cout<< "Oops\n";
else
std::cout << "Ok\n";
return 0;
}
UPD:
Strangely, to_upper, to_lower, to_tiltle and fold_case works ok. Problem is only with is_alpha
UPD2:
Further research showed, that function that use global locale work ok, but functions that take locale as a param fail.
boost::locale::to_upper( str ) works fine, but boost::to_upper_copy( str, loc ) fails.
I'm a university student, who need to study about making adc capturing in BeagleBone Black.
Everything goes really well. I can sampling the data from adc and even print the time stamp in each sample value. Then I check the sampling period of result which i got by using oscilloscope the check the wave from GPIO P8_10 by using "BeagleBoneBlack-GPIO" library Finally I realized that the sampling period is not stable at all.
And I assumed that I supposed to use Interrupt timer in BeagleBone Black. But my root-skill is pretty low to make it by my own.
Anyway. How can i make Interrupt timer by c++ through GPIO because I need to used the interrupt timer to control the adc to make the steady and stable sampling period such as 3ms.
data below is which version I am using, the code, and the result right now also
-BeagleBone Black
-Debian GNU/LInux 8.11 (jessie)
-Linux 5.0.3-bone5
-ARMv7 Processor rev2 (v7l)
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<unistd.h>
#include "GPIO/GPIOManager.h"
#include "GPIO/GPIOConst.h"
using namespace std;
#define LIN0_PATH "/sys/bus/iio/devices/iio:device0/in_voltage"
int readAnalog(int number){
stringstream ss;
ss << LIN0_PATH << number << "_raw";
fstream fs;
fs.open(ss.str().c_str(), fstream::in);
fs >> number;
fs.close();
return number;
}
int main(int argc, char* argv[ ]){
int i=0;
GPIO::GPIOManager* gp = GPIO::GPIOManager::getInstance();
int pin1 = GPIO::GPIOConst::getInstance()->getGpioByKey("P8_10");
gp->setDirection(pin1, GPIO::OUTPUT);
char buffer[26];
int millisec;
struct tm* tm_info;
struct timeval tv;
gettimeofday(&tv, NULL);
millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
if (millisec>=1000) {
millisec -=1000;
tv.tv_sec++;
} tm_info = localtime(&tv.tv_sec);
strftime(buffer, 26, "%d/%m/%Y %H:%M:%S", tm_info);
cout<<"print date and time"<<buffer<<":"<<millisec << endl;
for (int j=0;j<100;j++){
gp->setValue(pin1, GPIO::HIGH);
float value[j] = readAnalog(0)*(1.8/4096) ;
gp->setValue(pin1, GPIO::LOW);
usleep(300);
}
for (int j=0;j<100;j++){
cout << fixed;
cout.precision(3);
cout <<i<<";"<<value<< endl;
i++; }
return 0; }
And these are command to run the my file
g++ GPIO/GPIOConst.cpp GPIO/GPIOManager.cpp try.cpp
then
./a.out
and this is the result
print date and time10/04/2019 17:02:27:460
0;1.697
1;1.697
2;1.695
3;1.693
4;1.694
5;1.693
6;1.693
7;1.692
8;1.691
9;1.692
10;1.693
11;1.692
12;1.694
13;1.694
14;1.694
15;1.692
16;1.695
17;1.692
18;1.693
19;1.694
20;1.693
21;1.691
22;1.692
23;1.693
24;1.691
25;1.693
26;1.693
27;1.693
28;1.694
29;1.691
30;1.694
31;1.693
32;1.695
33;1.691
34;1.694
35;1.693
36;1.693
37;1.691
38;1.693
39;1.691
40;1.692
41;1.694
42;1.692
43;1.692
44;1.693
45;1.692
46;1.694
47;1.693
48;1.693
49;1.692
50;1.692
51;1.692
52;1.691
53;1.690
54;1.691
55;1.692
56;1.693
57;1.692
58;1.692
59;1.692
60;1.694
61;1.694
62;1.694
63;1.694
64;1.693
65;1.692
66;1.693
67;1.692
68;1.693
69;1.693
70;1.692
71;1.692
72;1.693
73;1.694
74;1.693
75;1.694
76;1.693
77;1.692
78;1.694
79;1.692
80;1.692
81;1.692
82;1.692
83;1.692
84;1.694
85;1.694
86;1.693
87;1.693
88;1.694
89;1.693
90;1.693
91;1.692
92;1.694
93;1.691
94;1.694
95;1.693
96;1.691
97;1.692
98;1.693
99;1.694
[and this is what i got from oscilloscope][1]
[1]: https://i.stack.imgur.com/FJSRe.jpg
It will be really great if there are anyone who would love to give me some advice. And If there are something concerning you guys. Please feel free to ask me.
Best Regard
Peeranut Noonurak
I am doing a simple project on arm based mini6410. I have debian package installed on mini. My project is to interface one IR motion sensor and I USB webcam with the mini6410. the working will be simple, whenever there will be any motion detected by IR sensor, the webcam will be on for 30 seconds save the images (over write the previous) and then off.
I have already cross comiled the Open CV code using arm-linux-gcc
For IR I am using GPE register.
Here I am stuck with a issue which I am unable to resolve. and even dont know how to resolve. OpenCv code is a cpp file camera.cpp and the file which deals with I/O ports is a C file named sensor.c. Now in that c file I am polling or whatever mechanism to check if the GPE register is 1 or not. If it is one, I should start the Open CV code which will start to capture images. further more this sensor.c file is not to be compiled rather made a module and then insmod on my mini6410.
However I dont know how to write c++ code in a c file. you can say i dont know how to call the OpenCV thing from the C file. as it is a module and within this i cant write the cpp code as then using namespace std and using namespace cv doesnot work.
i am new to embedded stuff and linux it self. so I wanted to know are there some possible solutions.
i am attaching my codes of both files.
This is sensor.c
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-q.h>
#include <mach/gpio-bank-e.h>
#include <mach/map.h>
#include <plat/regs-timer.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <mach/gpio-bank-k.h>
#define RLV 0x0FFF
unsigned Gpe;
unsigned sensor_value;
typedef struct
{
int delay;
} TIM_DEV;
static TIM_DEV TimDev;
static irqreturn_t INTHandler(int irq,void *TimDev)
{
Gpe = readl(S3C64XX_GPEDAT);
Gpe &= ~(0xF<<1);
readl(sensor_value, S3C64XX_GPEDAT);
while (sensor_value == 1)
{//1 means that IR sensor has detected a motion and given a value of +5 V
for (i = 0; i < 30; i++){
//CV_function();
// delay here such that delay(1 s) * 30 = 30 seconds
}
}
return IRQ_HANDLED;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.write = MyWrite,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
unsigned TimerControl;
unsigned TimerINTControl;
unsigned TimerCNTB;
unsigned TimerCMPB;
unsigned TimerCFG1;
unsigned Ge;
TimerControl = readl(S3C_TCON);
TimerINTControl = readl(S3C_TINT_CSTAT);
TimerCNTB = readl(S3C_TCNTB(0));
TimerCMPB = readl(S3C_TCMPB(0));
TimerCFG1 = readl(S3C_TCFG1);
TimerCFG1 &= ~(S3C_TCFG1_MUX0_MASK);
TimerCNTB = RLV;
TimerCMPB = 0;
writel(TimerCNTB, S3C_TCNTB(0));
writel(TimerCMPB, S3C_TCMPB(0));
writel(TimerCFG1, S3C_TCFG1);
TimerControl |= S3C_TCON_T0MANUALUPD;
TimerINTControl |= S3C_TINT_CSTAT_T0INTEN;
writel(TimerControl, S3C_TCON);
writel(TimerINTControl, S3C_TINT_CSTAT);
TimerControl = readl(S3C_TCON);
TimerControl |= S3C_TCON_T0RELOAD;
TimerControl &= ~S3C_TCON_T0MANUALUPD;
TimerControl |= S3C_TCON_T0START;
writel(TimerControl, S3C_TCON);
//////////////Here I am configuring my GPE as input/////////////
Ge = readl(S3C64XX_GPECON);
Ge &= ~(0xFFFF<<4);
Ge |= (0x0000<<4);
writel(Ge, S3C64XX_GPECON);
/////////////
misc_register(&misc);
ret = request_irq(IRQ_TIMER0, INTHandler, IRQF_SHARED, DEVICE_NAME, &TimDev);
if (ret)
{
return ret;
}
return ret;
}
static void __exit dev_exit(void)
{
free_irq(IRQ_TIMER0, &TimDev);
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("XYZ");
this is camera.cpp
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, const char** argv )
{CvCapture* capture = 0;
Mat frame, frameCopy, image;
capture = cvCaptureFromCAM( 2 );
if( !capture )
{
cout << "No camera detected" << endl;
}
if( capture )
{
cout << "In capture ..." << endl;
IplImage* iplImg = cvQueryFrame( capture );
frame = iplImg;
if( frame.empty() )
break;
if( iplImg->origin == IPL_ORIGIN_TL )
frame.copyTo( frameCopy );
else
flip( frame, frameCopy, 0 );
cvSaveImage("image.jpg" ,iplImg);
}
cvReleaseCapture( &capture );
return 0;
}
the for loop in the sensor.c file should have my this above code by some means
I hope you get the idea,
Thanks
The missing link in the code shown is a mechanism by which the user-space code shown above can get notification of a change in the GPIO pin detected by the device driver.
There are two obvious ways to achieve this:
Integrate the GPIO pin into the platform's GPIO resources and then use the generic sysfs mechanism from user-space. The Linux kernel GPIO documentation describes both kernel and user-space side of this.
Have your driver expose a sysfs node for the GPIO line. sysfs is fundamental to the Linux Driver Model. I suggest a thorough read of Linux Device Drivers 3rd Edition.
The user-space side of either method is similar: You open the sysfs resource exported by your module and then use either poll() or select() to block until an event occurs.
I foud out there is a new Boost.Process 0.5 but I cant see how to execute across Windows Linux and Mac ping or echo.
I got it working at leaast on Windows with simple:
#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/process.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/error_code.hpp>
namespace bp = boost::process;
namespace bpi = boost::process::initializers;
namespace bio = boost::iostreams;
int main()
{
bp::pipe p = bp::create_pipe();
{
bio::file_descriptor_sink sink(p.sink, bio::close_handle);
boost::filesystem::path p("C:/Windows/System32/cmd.exe");
boost::system::error_code ec;
bp::execute(
bpi::run_exe(p),
bpi::set_cmd_line(L"cmd /c echo --echo-stderr hello"),
bpi::bind_stdout(sink),
bpi::set_on_error(ec)
);
}
bio::file_descriptor_source source(p.source, bio::close_handle);
bio::stream<bio::file_descriptor_source> is(source);
std::string s;
is >> s;
std::cout << s << std::endl;
std::cin.get();
return 0;
}
On windows this works correctly but how to make it crossplatform to work also on Mac and Linux? (I am stupid and do not know how to write one path that would work for any Unix terminal (or at least for Linux Bash and mac default one)) So How to run commandline/terminal utils with Boost.Process 0.5 on Windows and Unix like OSs (better not writing path to terminal each time but just writting app like echo or ping and its arguments)?
...Found related code inside prevoius version:
std::string exe;
std::vector<std::string> args;
#if defined(BOOST_POSIX_API)
exe = "/bin/sh";
args.push_back("sh");
args.push_back("-c");
args.push_back(command);
#elif defined(BOOST_WINDOWS_API)
char sysdir[MAX_PATH];
UINT size = ::GetSystemDirectoryA(sysdir, sizeof(sysdir));
if (!size)
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_shell: GetWindowsDirectory failed"));
BOOST_ASSERT(size < MAX_PATH);
exe = std::string(sysdir) + (sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe");
args.push_back("cmd");
args.push_back("/c");
args.push_back(command);
#endif
Under boost.process 0.5 the shell_path() API was introduced so might the following will hook you up
#if defined(BOOST_POSIX_API)
#define SHELL_COMMAND_PREFIX "-c"
#elif defined(BOOST_WINDOWS_API)
#define SHELL_COMMAND_PREFIX "/c"
#endif
filesystem::path shellPath = process::shell_path();
std::string cl = shell_path().string() + " " SHELL_COMMAND_PREFIX " ";
cl += "ping 127.0.0.1";
execute(
set_cmd_line(cl),
throw_on_error()
);
If you really want to hide the #ifdef, I'd go on and edit the boost sources to return also the relevant command prefix (adding new API) , open source after all isn't it ? :).
You could find the relevant sources to edit at boost/process/windows/shell_path.hpp and boost/process/posix/shell_path.hpp
I need to format my ptime in such way Wed, 21 Jan 2004 19:51:30 GMT How to do such thing with boost? (so it would look like data format of HTTP servers Expires and Last-Modified and Date response headers )
#include <locale>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/date_time/posix_time/posix_time.hpp>
std::string current_time_formatted()
{
namespace bpt = boost::posix_time;
static char const* const fmt = "%a, %d %b %Y %H:%M:%S GMT";
std::ostringstream ss;
// assumes std::cout's locale has been set appropriately for the entire app
ss.imbue(std::locale(std::cout.getloc(), new bpt::time_facet(fmt)));
ss << bpt::second_clock::universal_time();
return ss.str();
}
See Date Time Input/Output for more information on the available format flags.